diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml
new file mode 100644
index 0000000..b44f9c9
--- /dev/null
+++ b/.github/workflows/performance.yml
@@ -0,0 +1,33 @@
+name: Build & Test Python Package
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - '**.yml'
+ - '**.py'
+ - pyproject.toml
+ - '**.sh'
+ - '**.html'
+
+jobs:
+ run-performance-tests:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+
+ - name: Install Hatch
+ run: pip install hatch
+
+ - name: Install dependencies
+ run: hatch env create dev
+
+ - name: Run performance tests
+ run: hatch run dev:perftest
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f23cd6f..9584ac9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,5 +19,6 @@ results/
oc_output.html
atest/testdoc_output/**
atest/mkdocs_test/**
+atest/mkdocs_test_perf/**
atest/mkdocs_test_custom/**
docs/mkdocs/site/**
\ No newline at end of file
diff --git a/atest/test_cli.py b/atest/acceptance/test_cli.py
similarity index 62%
rename from atest/test_cli.py
rename to atest/acceptance/test_cli.py
index 16b33d5..27b443c 100644
--- a/atest/test_cli.py
+++ b/atest/acceptance/test_cli.py
@@ -12,9 +12,9 @@ def test_cli_help():
assert "Welcome" in result.output
def test_cli_cmd():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir, "test_cli.robot")
- output = os.path.join(current_dir, "output_classic.html")
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "output_classic.html")
runner = CliRunner()
result = runner.invoke(main, [robot, output])
assert result.exit_code == 0
@@ -22,21 +22,10 @@ def test_cli_cmd():
assert "output_classic.html" in result.output
assert os.path.exists(output)
-def test_cli_cmd_big_suite():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir)
- output = os.path.join(current_dir, "output_big.html")
- runner = CliRunner()
- result = runner.invoke(main, [robot, output])
- assert result.exit_code == 0
- assert "Generated" in result.output
- assert "output_big.html" in result.output
- assert os.path.exists(output)
-
def test_cli_cmd_mkdocs():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir)
- output = os.path.join(current_dir, "mkdocs_test")
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "mkdocs_test")
if Path(output).exists():
shutil.rmtree(output)
os.mkdir(output)
@@ -48,9 +37,9 @@ def test_cli_cmd_mkdocs():
assert os.path.exists(os.path.join(output, "testdoc_output"))
def test_cli_cmd_github_prefix():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir)
- output = os.path.join(current_dir, "output_big.html")
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "output_big.html")
runner = CliRunner()
result = runner.invoke(main, ["-s", "github::https://github.com/project-name", "--verbose", robot, output])
assert result.exit_code == 0
@@ -60,9 +49,9 @@ def test_cli_cmd_github_prefix():
assert os.path.exists(output)
def test_cli_cmd_gitlab_prefix():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir)
- output = os.path.join(current_dir, "output_big.html")
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "output_big.html")
runner = CliRunner()
result = runner.invoke(main, ["-s", "gitlab::https://gitlab.com/project-name", "--verbose", robot, output])
assert result.exit_code == 0
@@ -72,10 +61,10 @@ def test_cli_cmd_gitlab_prefix():
assert os.path.exists(output)
def test_cli_cmd_mkdocs_custom_template():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir)
- output = os.path.join(current_dir, "mkdocs_test_custom")
- templ_dir = Path(__file__).parent.parent / "examples" / "mkdocs" / "default"
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "mkdocs_test_custom")
+ templ_dir = Path(__file__).parent.parent.parent / "examples" / "mkdocs" / "default"
if Path(output).exists():
shutil.rmtree(output)
os.mkdir(output)
@@ -88,9 +77,9 @@ def test_cli_cmd_mkdocs_custom_template():
def test_cli_cmd_verbose():
- current_dir = os.path.dirname(os.path.abspath(__file__))
- robot = os.path.join(current_dir, "test_cli.robot")
- output = os.path.join(current_dir, "output.html")
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "acceptance")
+ output = os.path.join(parent_dir, "output.html")
runner = CliRunner()
result = runner.invoke(main, [robot, output, "-v"])
assert result.exit_code == 0
diff --git a/atest/config/config_with_colors.toml b/atest/config/config_with_colors.toml
deleted file mode 100644
index 3e38030..0000000
--- a/atest/config/config_with_colors.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-sourceprefix = "gitlab::https://gitlab.com/myrepo/repo_path"
-hide_suite_doc = true
-verbose_mode = true
-
-[colors]
-# DEFAULT THEME:
-default = "dark"
-# OR CUSTOM THEME:
-# background = "#000028"
-# inner_color = "#000028"
-# button_active_color = "#193966"
-# button_hover_color = "#193966"
-# border_color = "#CCCCCC"
-# text_color = "#CCCCCC"
-# title_color = "#00ffb9"
-# robot_icon = "#00ffb9"
diff --git a/atest/config/testdoc.toml b/atest/config/testdoc.toml
deleted file mode 100644
index 66b725a..0000000
--- a/atest/config/testdoc.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-sourceprefix = "gitlab::https://gitlab.com/myrepo/repo_path"
-hide_suite_doc = true
-verbose_mode = true
-
-include = ["TagA", "TagB"]
-exclude = ["TagC"]
-
-[metadata]
-Author = "Marvin Klerx"
-Version = "1.0.0"
diff --git a/atest/config_pyproject/example_pyproject.toml b/atest/config_pyproject/example_pyproject.toml
deleted file mode 100644
index cfbed80..0000000
--- a/atest/config_pyproject/example_pyproject.toml
+++ /dev/null
@@ -1,32 +0,0 @@
-[tool.testdoc]
-title = "New title of HTML document"
-name = "New name of root suite element"
-doc = "New doc text of root suite element"
-sourceprefix = "gitlab::https://gitlab.com/myrepo/repo_path"
-include = ["TagA", "TagB"]
-exclude = ["TagC"]
-hide_tags = true
-hide_test_doc = true
-hide_suite_doc = true
-hide_source = true
-hide_keywords = true
-style = "blue"
-verbose_mode = false
-
-[tool.testdoc.metadata]
-Author = "Your-Name"
-Version = "1.0.0"
-Source = "AnySourceAsMetaData"
-
-[tool.testdoc.colors]
-# Use predefined theme:
-default = "blue"
-# or custom colors:
-background = "#000028"
-inner_color = "#000028"
-button_active_color = "#193966"
-button_hover_color = "#193966"
-border_color = "#CCCCCC"
-text_color = "#CCCCCC"
-title_color = "#00ffb9"
-robot_icon = "#00ffb9"
diff --git a/atest/performance/test_performance.py b/atest/performance/test_performance.py
new file mode 100644
index 0000000..d766775
--- /dev/null
+++ b/atest/performance/test_performance.py
@@ -0,0 +1,19 @@
+import os
+from pathlib import Path
+import shutil
+from click.testing import CliRunner
+from testdoc.cli import main
+
+def test_cli_cmd_mkdocs_performance():
+ parent_dir = Path(__file__).parent.parent
+ robot = os.path.join(parent_dir, "testdata", "performance", "tests")
+ output = os.path.join(parent_dir, "mkdocs_test_perf")
+ if Path(output).exists():
+ shutil.rmtree(output)
+ os.mkdir(output)
+ runner = CliRunner()
+ result = runner.invoke(main, ["--mkdocs", robot, output])
+ assert result.exit_code == 0
+ assert "Generated mkdocs pages here" in result.stdout
+ assert output in result.stdout
+ assert os.path.exists(os.path.join(output, "testdoc_output"))
diff --git a/atest/second_test_cli.robot b/atest/second_test_cli.robot
deleted file mode 100644
index a2ab41b..0000000
--- a/atest/second_test_cli.robot
+++ /dev/null
@@ -1,15 +0,0 @@
-*** Settings ***
-Name Suite 2
-Documentation Basic Console Logging - Suite Doc
-... Documentation in second line
-Metadata Author=Marvin Klerx
-Metadata Creation=January 2026
-Test Tags Global-Tag
-
-
-*** Test Cases ***
-Suite 2 - TC-001
- [Documentation] Basic Console Logging
- [Tags] RobotTestDoc
-
- Log Log message in suite 2 - TC-001
diff --git a/atest/test_cli.robot b/atest/test_cli.robot
deleted file mode 100644
index 476fa3c..0000000
--- a/atest/test_cli.robot
+++ /dev/null
@@ -1,32 +0,0 @@
-*** Settings ***
-Metadata Author=Marvin Klerx
-Metadata Creation=March 2025
-Test Tags Global-Tag
-
-
-*** Test Cases ***
-Log Message
- [Documentation] Basic Console Logging
- ... Test Doc in second line
- ...
- ... Test doc in third line
- ... \nfourth line
- [Tags] RobotTestDoc
-
- # this is my commentary
- Log RobotFramework Test Documentation Generator!
-
-Test without docs
- Log Test without Doc
-
-
-*** Keywords ***
-MyUserKeword
- [Documentation] User Keyword
-
- Log This is a user keyword
-
-My Second User Keyword
- [Documentation] User Keyword
-
- Log This is a user keyword
diff --git a/atest/testcases/component_a/suite_a.robot b/atest/testdata/acceptance/testcases/component_a/suite_a.robot
similarity index 100%
rename from atest/testcases/component_a/suite_a.robot
rename to atest/testdata/acceptance/testcases/component_a/suite_a.robot
diff --git a/atest/testcases/component_a/suite_without_tags.robot b/atest/testdata/acceptance/testcases/component_a/suite_without_tags.robot
similarity index 100%
rename from atest/testcases/component_a/suite_without_tags.robot
rename to atest/testdata/acceptance/testcases/component_a/suite_without_tags.robot
diff --git a/atest/testcases/component_b/subcomponent_b/subsuite_b.robot b/atest/testdata/acceptance/testcases/component_b/subcomponent_b/subsuite_b.robot
similarity index 100%
rename from atest/testcases/component_b/subcomponent_b/subsuite_b.robot
rename to atest/testdata/acceptance/testcases/component_b/subcomponent_b/subsuite_b.robot
diff --git a/atest/testcases/component_b/suite_b.robot b/atest/testdata/acceptance/testcases/component_b/suite_b.robot
similarity index 100%
rename from atest/testcases/component_b/suite_b.robot
rename to atest/testdata/acceptance/testcases/component_b/suite_b.robot
diff --git a/atest/testdata/performance/resources/common/common.robot b/atest/testdata/performance/resources/common/common.robot
new file mode 100755
index 0000000..1a32838
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common.robot
@@ -0,0 +1,1275 @@
+*** Settings ***
+Library String
+# Library Dialogs
+Library OperatingSystem
+Library Process
+Library Collections
+Library BuiltIn
+Library DateTime
+Library RequestsLibrary
+Library DatabaseLibrary
+Library ../../resources/libraries/common.py
+# Library Telnet
+
+*** Variables ***
+# *** DB VARIABLES ***
+${db_engine}
+${db_port}
+${default_db_host} 127.0.0.1
+${default_db_name} eu-docker
+${default_db_password} secret
+${default_db_port} 3306
+${default_db_port_postgres} 5432
+${default_db_user} spryker
+${default_db_engine} pymysql
+# ${default_db_engine} psycopg2
+
+# *** DOCKER VARIABLES ***
+${docker}
+${default_docker} ${False}
+${docker_db_host} database
+${docker_cli_url} http://cli:9000
+${cli_path} ..
+
+# *** CLI VARIABLES ***
+${project_location}
+${ignore_console}
+${default_ignore_console} ${True}
+
+# *** COMMON VARIABLES ***
+${verify_ssl} false
+
+# *** DMS VARIABLES ***
+${dms}
+${default_dms} ${False}
+
+# *** SSP VARIABLES ***
+${is_ssp}
+${default_is_ssp} ${False}
+
+*** Keywords ***
+Common_suite_setup
+ [Documentation] Basic steps before each suite
+ [Arguments] ${skip_if_already_executed}=False
+ Remove Files ${OUTPUTDIR}/selenium-screenshot-*.png
+ Remove Files ${OUTPUTDIR}/*.png
+ Remove Files ${OUTPUTDIR}/*.yml
+
+ Generate global random variable
+ ${random_id}= Generate Random String 5 [NUMBERS]
+ ${random_str}= Generate Random String 5 [LETTERS]
+ ${random_str_store}= Generate Random String 2 [UPPER]
+ ${random_str_password}= Generate Random String 5 [LETTERS]
+ ${random_id_password}= Generate Random String 5 [NUMBERS]
+
+ Set Global Variable ${random_id}
+ Set Global Variable ${random_str}
+ Set Global Variable ${random_str_store}
+ Set Global Variable ${random_id_password}
+ Set Global Variable ${random_str_password}
+
+ ${today}= Get Current Date result_format=%Y-%m-%d
+ Set Global Variable ${today}
+
+ ${already_executed}= Run Keyword And Return Status Variable Should Exist ${setup_done}
+ IF ${already_executed} and ${skip_if_already_executed}
+ # Setup is already done, skip
+ RETURN
+ END
+ Load Variables ${env}
+ Overwrite env variables
+ IF ${docker}
+ Set Global Variable ${db_host} ${docker_db_host}
+ END
+ VAR ${setup_done} ${True} scope=GLOBAL
+
+Generate global random variable
+ ${excluded_ranges}= Evaluate [str(i).zfill(3) for i in list(range(1, 220)) + [666]]
+ ${random}= Evaluate random.randint(300, 99999)
+ WHILE any(ex in str(${random}) for ex in ${excluded_ranges})
+ ${random}= Evaluate random.randint(300, 99999)
+ END
+ ${random}= Convert To String ${random}
+ Set Global Variable ${random}
+
+Should Test Run
+ Log Many @{Test Tags}
+ ${dms_state}= Convert To String ${dms}
+ IF '${dms_state}' != 'True'
+ IF 'dms-on' in @{Test Tags}
+ Skip
+ END
+ ELSE
+ IF 'dms-off' in @{Test Tags}
+ Skip
+ END
+ END
+
+Load Variables
+ [Documentation] Keyword is used to load variable values from the environment file passed during execution. This Keyword is used during suite setup.
+ ... It accepts the name of the environment as specified at the beginning of an environment file e.g. ``"environment": "api_suite"``.
+ ...
+ ... These variables are loaded and usable throughout all tests of the test suite, if this keyword is called during suite setup.
+ ...
+ ... *Example:*
+ ...
+ ... ``Load Variables ${env}``
+ ...
+ ... ``Load Variables api_suite``
+ [Arguments] ${env}
+ ${variables_already_loaded}= Run Keyword And Return Status Variable Should Exist ${env_variables_loaded}
+ IF not ${variables_already_loaded}
+ &{vars}= Define Environment Variables From Json File ${env}
+ FOR ${key} ${value} IN &{vars}
+ ${var_value}= Get Variable Value ${${key}} ${value}
+ Set Global Variable ${${key}} ${var_value}
+ END
+ VAR ${env_variables_loaded} ${True} scope=GLOBAL
+ ELSE
+ Log Environment variables are already loaded
+ END
+
+Overwrite env variables
+ IF '${project_location}' == '${EMPTY}'
+ Set Global Variable ${cli_path} ${cli_path}
+ ELSE
+ Set Global Variable ${cli_path} ${project_location}
+ END
+ IF '${ignore_console}' == '${EMPTY}'
+ Set Global Variable ${ignore_console} ${default_ignore_console}
+ ELSE
+ Set Global Variable ${ignore_console} ${ignore_console}
+ END
+ IF '${docker}' == '${EMPTY}'
+ Set Global Variable ${docker} ${default_docker}
+ ELSE
+ Set Global Variable ${docker} ${docker}
+ END
+ IF '${dms}' == '${EMPTY}'
+ Set Global Variable ${dms} ${default_dms}
+ ELSE
+ Set Global Variable ${dms} ${dms}
+ END
+ IF '${is_ssp}' == '${EMPTY}'
+ Set Global Variable ${is_ssp} ${default_is_ssp}
+ ELSE
+ ${is_ssp}= Convert To String ${is_ssp}
+ ${is_ssp}= Convert To Lower Case ${is_ssp}
+ IF '${is_ssp}' == 'yes' Set Global Variable ${is_ssp} true
+ Set Global Variable ${is_ssp} ${is_ssp}
+ END
+ ${dms}= Convert To String ${dms}
+ ${dms}= Convert To Lower Case ${dms}
+ IF '${dms}' == 'true' Set Global Variable ${dms} ${True}
+ IF '${dms}' == 'false' Set Global Variable ${dms} ${False}
+ IF '${dms}' == 'on' Set Global Variable ${dms} ${True}
+ IF '${dms}' == 'off' Set Global Variable ${dms} ${False}
+ IF '${ignore_console}' == 'true' Set Global Variable ${ignore_console} ${True}
+ IF '${ignore_console}' == 'false' Set Global Variable ${ignore_console} ${False}
+ IF '${docker}' == 'true' Set Global Variable ${docker} ${True}
+ IF '${docker}' == 'false' Set Global Variable ${docker} ${False}
+ ${verify_ssl}= Convert To String ${verify_ssl}
+ ${verify_ssl}= Convert To Lower Case ${verify_ssl}
+ IF '${verify_ssl}' == 'true'
+ Set Global Variable ${verify_ssl} ${True}
+ ELSE
+ Set Global Variable ${verify_ssl} ${False}
+ END
+
+Set Up Keyword Arguments
+ [Arguments] @{args}
+ &{arguments}= Fill Variables From Text String @{args}
+ FOR ${key} ${value} IN &{arguments}
+ ${var_value}= Set Variable ${value}
+ Set Test Variable ${${key}} ${var_value}
+ END
+ RETURN &{arguments}
+
+Variable datatype should be:
+ [Arguments] ${variable} ${expected_data_type}
+ ${actual_data_type}= Evaluate datatype of a variable: ${variable}
+ Should Be Equal ${actual_data_type} ${expected_data_type}
+
+Evaluate datatype of a variable:
+ [Arguments] ${variable}
+ ${data_type}= Evaluate type($variable).__name__
+ RETURN ${data_type}
+ #Example of assertions:
+ # ${is int}= Evaluate isinstance($variable, int) # will be True
+ # ${is string}= Evaluate isinstance($variable, str) # will be False
+
+Convert string to List by separator:
+ [Arguments] ${string} ${separator}=,
+ ${convertedList}= Split String ${string} ${separator}
+ ${convertedList}= Set Test Variable ${convertedList}
+ RETURN ${convertedList}
+
+Remove leading and trailing whitespace from a string:
+ [Arguments] ${string}
+ ${string}= Replace String Using Regexp ${string} (^[ ]+|[ ]+$) ${EMPTY}
+ Set Global Variable ${string}
+ RETURN ${string}
+
+Connect to Spryker DB
+ [Documentation] This keyword allows to connect to Spryker DB.
+ ... Supports both MariaDB and PostgeSQL.
+ ...
+ ... To specify the expected DB engine, use ``db_engine`` variable. Default one -> *MariaDB*
+ ...
+ ... *Example:*
+ ... ``robot -v env:api_suite -v db_engine:psycopg2``
+ ...
+ ... with the example above you'll use PostgreSQL DB engine
+ Set Log Level NONE
+ ${db_name}= Set Variable If '${db_name}' == '${EMPTY}' ${default_db_name} ${db_name}
+ ${db_user}= Set Variable If '${db_user}' == '${EMPTY}' ${default_db_user} ${db_user}
+ ${db_password}= Set Variable If '${db_password}' == '${EMPTY}' ${default_db_password} ${db_password}
+ ${db_host}= Set Variable If '${db_host}' == '${EMPTY}' ${default_db_host} ${db_host}
+ ${db_engine}= Set Variable If '${db_engine}' == '${EMPTY}' ${default_db_engine} ${db_engine}
+ ${db_engine}= Convert To Lower Case ${db_engine}
+ IF '${db_engine}' == 'mysql'
+ ${db_engine}= Set Variable pymysql
+ ELSE IF '${db_engine}' == 'mariadb'
+ ${db_engine}= Set Variable pymysql
+ ELSE IF '${db_engine}' == 'maria'
+ ${db_engine}= Set Variable pymysql
+ ELSE IF '${db_engine}' == 'postgresql'
+ ${db_engine}= Set Variable psycopg2
+ ELSE IF '${db_engine}' == 'postgres'
+ ${db_engine}= Set Variable psycopg2
+ END
+ IF '${db_engine}' == 'psycopg2'
+ ${db_port}= Set Variable If '${db_port}' == '${EMPTY}' ${db_port_postgres_env} ${db_port}
+ IF '${db_port_postgres_env}' == '${EMPTY}'
+ ${db_port}= Set Variable If '${db_port_postgres_env}' == '${EMPTY}' ${default_db_port_postgres} ${db_port_postgres_env}
+ END
+ ELSE
+ ${db_port}= Set Variable If '${db_port}' == '${EMPTY}' ${db_port_env} ${db_port}
+ IF '${db_port_env}' == '${EMPTY}'
+ ${db_port}= Set Variable If '${db_port_env}' == '${EMPTY}' ${default_db_port} ${db_port_env}
+ END
+ END
+ Set Test Variable ${db_engine}
+ Disconnect From Database
+ Connect To Database ${db_engine} ${db_name} ${db_user} ${db_password} ${db_host} ${db_port}
+ Reset Log Level
+
+Save the result of a SELECT DB query to a variable:
+ [Documentation] This keyword saves any value which you receive from DB using SQL query ``{sql_query}`` to a test variable called ``{variable_name}``.
+ ...
+ ... It can be used to save a value returned by any query into a custom test variable.
+ ... This variable, once created, can be used during the specific test where this keyword is used and can be re-used by the keywords that follow this keyword in the test.
+ ... It will not be visible to other tests.
+ ... NOTE: Make sure that you expect only 1 value from DB, you can also check your query via external SQL tool.
+ ...
+ ... *Examples:*
+ ...
+ ... ``Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key``
+ [Arguments] ${sql_query} ${variable_name}
+ Connect to Spryker DB
+ ${var_value} = Query ${sql_query}
+ Disconnect From Database
+ ${var_value}= Convert To String ${var_value}
+ ${var_value}= Replace String ${var_value} ' ${EMPTY}
+ ${var_value}= Replace String ${var_value} , ${EMPTY}
+ ${var_value}= Replace String ${var_value} ( ${EMPTY}
+ ${var_value}= Replace String ${var_value} ) ${EMPTY}
+ ${var_value}= Replace String ${var_value} [ ${EMPTY}
+ ${var_value}= Replace String ${var_value} ] ${EMPTY}
+ Set Test Variable ${${variable_name}} ${var_value}
+ RETURN ${variable_name}
+
+Send GET request and return status code:
+ [Arguments] ${url} ${timeout}=5
+ ${response}= GET ${url} timeout=${timeout} allow_redirects=true expected_status=ANY
+ Set Test Variable ${response.status_code} ${response.status_code}
+ RETURN ${response.status_code}
+
+Run console command
+ [Documentation] This keyword executes console command using provided command and parameters. If docker is enabled, it will execute the command using docker.
+ ... *Example:*
+ ...
+ ... ``Run console command command=publish:trigger-events parameters=-r service_point storeName=DE``
+ ...
+ [Arguments] ${command} ${storeName}=DE
+ IF ${dms}
+ IF '${storeName}' == 'DE'
+ ${storeName}= Set Variable EU
+ END
+ IF '${storeName}' == 'AT'
+ ${storeName}= Set Variable EU
+ END
+ IF '${storeName}' == 'US'
+ ${storeName}= Set Variable US
+ END
+ ${consoleCommand}= Set Variable cd ${cli_path} && SPRYKER_CURRENT_REGION=${storeName} docker/sdk ${command}
+ IF ${docker}
+ ${consoleCommand}= Set Variable curl --request POST -LsS --data "SPRYKER_CURRENT_REGION='${storeName}' COMMAND='${command}' cli.sh" --max-time 1000 --url "${docker_cli_url}/console"
+ TRY
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'.
+ EXCEPT
+ Sleep 1s
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'.
+ END
+ END
+ Log ${ignore_console}
+ IF ${ignore_console} != True and not ${docker}
+ TRY
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'
+ EXCEPT
+ Sleep 1s
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'
+ END
+ END
+ ELSE
+ ${consoleCommand}= Set Variable cd ${cli_path} && APPLICATION_STORE=${storeName} docker/sdk ${command}
+ IF ${docker}
+ ${consoleCommand}= Set Variable curl --request POST -LsS --data "APPLICATION_STORE='${storeName}' COMMAND='${command}' cli.sh" --max-time 1000 --url "${docker_cli_url}/console"
+ TRY
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'.
+ EXCEPT
+ Sleep 1s
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'.
+ END
+ END
+ IF ${ignore_console} != True and not ${docker}
+ TRY
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'
+ EXCEPT
+ Sleep 200ms
+ ${rc} ${output}= Run And Return RC And Output ${consoleCommand}
+ Log ${output}
+ Should Be Equal As Integers ${rc} 0 message=CLI output:"${output}". CLI command can't be executed. Check '{docker}', '{ignore_console}' variables value and cli execution path: '{cli_path}'
+ END
+ END
+ END
+
+Trigger p&s
+ [Arguments] ${timeout}=0ms ${storeName}=DE
+ Run console command console queue:worker:start --stop-when-empty ${storeName}
+ IF ${docker} or ${ignore_console} != True Sleep ${timeout}
+
+Trigger API specification update
+ [Arguments] ${timeout}=200ms ${storeName}=DE
+ IF ${docker}
+ Run console command glue api:generate:documentation --invalidated-after-interval 90sec ${storeName}
+ ELSE
+ Run console command cli glue api:generate:documentation --invalidated-after-interval 90sec ${storeName}
+ END
+ IF ${docker} or ${ignore_console} != True Sleep ${timeout}
+
+Trigger multistore p&s
+ [Arguments] ${timeout}=0ms
+ IF ${dms}
+ Trigger p&s ${timeout} DE
+ ELSE
+ Trigger p&s ${timeout} DE
+ Trigger p&s ${timeout} AT
+ END
+
+Trigger oms
+ [Arguments] ${timeout}=10ms
+ IF ${dms}
+ Run console command console oms:check-timeout DE
+ Run console command console oms:check-condition DE
+ ELSE
+ Run console command console oms:check-timeout DE
+ Run console command console oms:check-timeout AT
+ Run console command console oms:check-condition DE
+ Run console command console oms:check-condition AT
+ END
+ IF ${docker} or ${ignore_console} != True Sleep ${timeout}
+
+Trigger publish trigger-events
+ [Documentation] This keyword triggers publish:trigger-events console command using provided resource, path and store.
+ ... *Example:*
+ ...
+ ... ``Trigger publish trigger-events resource=service_point storeName=DE timeout=5s``
+ ...
+ [Arguments] ${resource} ${storeName}=DE ${timeout}=0ms
+ Run console command console publish:trigger-events -r ${resource} ${storeName}
+ Trigger p&s ${timeout} ${storeName}
+
+Get next id from table
+ [Documentation] This keyword returns next ID from the given table.
+ ... *Example:*
+ ...
+ ... ``Get next id from table tableName=product idColumnName=id_product``
+ ...
+ [Arguments] ${tableName} ${idColumnName}
+ Connect to Spryker DB
+ ${lastId}= Query SELECT ${idColumnName} FROM ${tableName} ORDER BY ${idColumnName} DESC LIMIT 1;
+ ${newId}= Set Variable ${EMPTY}
+ ${lastIdLength}= Get Length ${lastId}
+ IF ${lastIdLength} > 0
+ ${newId}= Evaluate ${lastId[0][0]} + 1
+ ELSE
+ ${newId}= Evaluate 1
+ END
+ Disconnect From Database
+ RETURN ${newId}
+
+Get concrete product sku by id from DB:
+ [Documentation] This keyword returns product concrete sku from DB found by id_product. Returns '${concrete_sku}' variable
+ ... *Example:*
+ ...
+ ... ``Get concrete product sku by id from DB: ${id_product}``
+ ...
+ [Arguments] ${id_product}
+ Connect to Spryker DB
+ ${concrete_sku}= Query select sku from spy_product WHERE id_product='${id_product}';
+ ${concrete_sku}= Get From List ${concrete_sku} 0
+ ${concrete_sku}= Convert To String ${concrete_sku[0]}
+ Set Test Variable ${concrete_sku} ${concrete_sku}
+ Disconnect From Database
+
+Create giftcode in Database:
+ [Documentation] This keyword creates a new entry in the DB table spy_gift_card with the name, value and gift-card code.
+ ... *Example:*
+ ...
+ ... ``Create giftcode in Database: checkout_${random} ${gift_card.amount}``
+ ...
+ [Arguments] ${spy_gift_card_code} ${spy_gift_card_value}
+ ${amount}= Evaluate ${spy_gift_card_value} / 100
+ ${amount}= Evaluate "%.f" % ${amount}
+ ${new_id}= Get next id from table spy_gift_card id_gift_card
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_gift_card (code,name,currency_iso_code,value) value ('${spy_gift_card_code}','Gift_card_${amount}','EUR','${spy_gift_card_value}')
+ ELSE
+ Execute Sql String INSERT INTO spy_gift_card (id_gift_card, code, name, currency_iso_code, value) VALUES (${new_id}, '${spy_gift_card_code}', 'Gift_card_${amount}', 'EUR', '${spy_gift_card_value}');
+ END
+ Disconnect From Database
+
+Update order status in Database:
+ [Documentation] This keyword updates order status in database to any required status. This allows to skip going through the order workflow manually
+ ... but just switch to the status you need to create a test.
+ ... There is no separate endpoint to update order status and this keyword allows to do this via database value update.
+ ... *Example:*
+ ...
+ ... ``Update order status in Database: 7 shipped``
+ [Arguments] ${order_item_status_name} ${uuid_to_use}
+ Connect to Spryker DB
+ ${new_id}= Set Variable ${EMPTY}
+ ${state_id}= Set Variable ${EMPTY}
+ ${last_id}= Query SELECT id_oms_order_item_state FROM spy_oms_order_item_state ORDER BY id_oms_order_item_state DESC LIMIT 1;
+ ${expected_state_id}= Query SELECT id_oms_order_item_state FROM spy_oms_order_item_state WHERE name='${order_item_status_name}';
+ ${last_id_length}= Get Length ${last_id}
+ ${expected_state_id_length}= Get Length ${expected_state_id}
+ IF ${expected_state_id_length} > 0
+ ${state_id}= Set Variable ${expected_state_id[0][0]}
+ ELSE
+ IF ${last_id_length} > 0
+ ${new_id}= Evaluate ${last_id[0][0]} + 1
+ ELSE
+ ${new_id}= Evaluate 1
+ END
+ Execute Sql String INSERT INTO spy_oms_order_item_state (id_oms_order_item_state, name) VALUES (${new_id}, '${order_item_status_name}');
+ ${state_id}= Set Variable ${new_id}
+ END
+ Execute Sql String update spy_sales_order_item set fk_oms_order_item_state = '${state_id}' where uuid= '${uuid_to_use}'
+ Disconnect From Database
+
+Create merchant order for the item in DB and change status:
+ [Documentation] This keyword creates new merchant order in the DB and sets the desired status . This allows to skip going through the order workflow manually
+ ... but just switch to the status you need to create a test.
+ ... There is no separate endpoint to update order status and this keyword allows to do this via database value update.
+ ... *Example:*
+ ...
+ ... ``Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.sony_experts.merchant_reference}``
+ [Arguments] ${order_item_status_name} ${uuid_to_use} ${merchant_reference}
+ Connect to Spryker DB
+ ${new_id}= Set Variable ${EMPTY}
+ ${state_id}= Set Variable ${EMPTY}
+ ${last_id}= Query SELECT id_state_machine_item_state FROM spy_state_machine_item_state ORDER BY id_state_machine_item_state DESC LIMIT 1;
+ ${expected_state_id}= Query SELECT id_state_machine_item_state FROM spy_state_machine_item_state WHERE name='${order_item_status_name}';
+ ${last_id_length}= Get Length ${last_id}
+ IF ${last_id_length} == 0
+ ${state_id}= Set Variable 1
+ ${state_id}= Convert To String ${state_id}
+ END
+ ${expected_state_id_length}= Get Length ${expected_state_id}
+ IF ${expected_state_id_length} > 0
+ ${state_id}= Set Variable ${expected_state_id[0][0]}
+ ELSE
+ IF ${last_id_length} > 0
+ ${state_id}= Evaluate ${last_id[0][0]} + 1
+ ELSE
+ ${state_id}= Evaluate 1
+ END
+ Execute Sql String INSERT INTO spy_state_machine_item_state (id_state_machine_item_state, fk_state_machine_process, name) VALUES (${state_id}, 2, '${order_item_status_name}');
+ END
+ ${last_order_item_id}= Query SELECT id_merchant_sales_order_item from spy_merchant_sales_order_item order by id_merchant_sales_order_item desc limit 1;
+ ${last_order_item_id_length}= Get Length ${last_order_item_id}
+ IF ${last_order_item_id_length} == 0
+ ${new_order_item_id}= Set variable 1
+ ${new_order_item_id}= Convert To String ${new_order_item_id}
+ END
+ IF ${last_order_item_id_length} > 0
+ ${new_order_item_id}= Evaluate ${last_order_item_id[0][0]} +1
+ ELSE
+ ${new_order_item_id}= Set Variable ${new_order_item_id}
+ END
+ ${last_merchant_order_id}= Query SELECT id_merchant_sales_order from spy_merchant_sales_order order by id_merchant_sales_order desc limit 1;
+ ${last_merchant_order_id_length}= Get Length ${last_merchant_order_id}
+ IF ${last_merchant_order_id_length} == 0
+ ${new_merchant_order_id}= Set Variable 1
+ ${new_merchant_order_id}= Convert To String ${new_merchant_order_id}
+ END
+ IF ${last_merchant_order_id_length} > 0
+ ${new_merchant_order_id}= Evaluate ${last_merchant_order_id[0][0]} +1
+ ELSE
+ ${new_merchant_order_id}= Set Variable ${new_merchant_order_id}
+ END
+ ${sales_order_id}= Query SELECT fk_sales_order from spy_sales_order_item where uuid='${uuid_to_use}';
+ ${sales_order_id}= Set Variable ${sales_order_id[0][0]}
+ Execute Sql String INSERT INTO spy_merchant_sales_order (id_merchant_sales_order, fk_sales_order, merchant_reference, merchant_sales_order_reference) VALUES (${new_merchant_order_id}, ${sales_order_id}, '${merchant_reference}', 'DE--${sales_order_id}--${merchant_reference}');
+ ${last_merchant_order_item_id}= Query SELECT id_merchant_sales_order from spy_merchant_sales_order order by id_merchant_sales_order desc limit 1;
+ ${last_merchant_order_item_id_length}= Get Length ${last_merchant_order_item_id}
+ IF ${last_merchant_order_item_id_length} > 0
+ ${new_merchant_order_item_id}= Evaluate ${last_merchant_order_item_id[0][0]} +1
+ END
+ ${sales_order_item_id}= Query SELECT id_sales_order_item from spy_sales_order_item where uuid='${uuid_to_use}';
+ ${sales_order_item_id}= Set Variable ${sales_order_item_id[0][0]}
+ ${random_merchant_order_item_reference}= Generate Random String 10 [NUMBERS]
+ Execute Sql String INSERT INTO spy_merchant_sales_order_item (id_merchant_sales_order_item, fk_merchant_sales_order, fk_sales_order_item, fk_state_machine_item_state, merchant_order_item_reference) VALUES (${new_merchant_order_item_id}, ${new_merchant_order_id}, ${sales_order_item_id}, ${state_id}, '${random_merchant_order_item_reference}');
+ Disconnect From Database
+
+Delete country by iso2_code in Database:
+ [Documentation] This keyword deletes a country by iso2_code in the DB table spy_country.
+ ... *Example:*
+ ...
+ ... ``Delete country by iso2_code in Database: DE``
+ ...
+ [Arguments] ${iso2_code}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_country WHERE iso2_code = '${iso2_code}';
+ Disconnect From Database
+
+Delete url by url name in Database:
+ [Documentation] This keyword deletes a url by url name in the DB table spy_url.
+ ... *Example:*
+ ...
+ ... ``Delete url by url name in Database: test``
+ ...
+ [Arguments] ${url}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_url WHERE url = '${url}';
+ Disconnect From Database
+
+Verify that url is present in the Database:
+ [Documentation] This keyword verifies that url is present in the DB table spy_url.
+ ... *Example:*
+ ...
+ ... ``Verify that url is present in the Database: test``
+ ...
+ [Arguments] ${url}
+ Connect to Spryker DB
+ ${db_url}= Query SELECT url FROM spy_url WHERE url = '${url}' LIMIT 1;
+ ${db_url}= Set Variable ${db_url[0][0]}
+ Disconnect From Database
+ Should Be Equal ${url} ${db_url}
+
+Update dynamic entity configuration in Database:
+ [Documentation] This keyword update dynamic entity configuration in the DB table spy_dynamic_entity_configuration if configuration exists.
+ ... *Example:*
+ ...
+ ... ``Update dynamic entity configuration in Database: country spy_country 1 {"identifier":"id_country","fields":[...]}``
+ ...
+ [Arguments] ${table_alias} ${table_name} ${is_active} ${definition}
+ Connect to Spryker DB
+ Execute Sql String update spy_dynamic_entity_configuration set table_alias = '${table_alias}', table_name = '${table_name}', is_active = '${is_active}', definition = '${definition}' where table_alias = '${table_alias}';
+ Disconnect From Database
+
+I add 'admin' role to company user and get company_user_uuid:
+ [Documentation] This is a helper keyword which sets the 'Admin' role to the company user if it is not already set and returns the uuid of this company user. Requires: company user email, company key and business unit key
+ ... *Example:*
+ ...
+ ... ``Add 'admin' role to company user and return company_user_uuid: anne.boleyn@spryker.com BoB-Hotel-Jim business-unit-jim-1``
+ [Arguments] ${email} ${company_key} ${business_unit_key}
+ Connect to Spryker DB
+ Set Log Level NONE
+ ${id_customer}= Query select id_customer from spy_customer WHERE email='${email}'
+ ${id_customer}= Evaluate ${id_customer[0][0]}+0
+ IF '${db_engine}' == 'pymysql'
+ ${id_business_unit}= Query select id_company_business_unit from spy_company_business_unit where `key`='${business_unit_key}'
+ ELSE
+ ${id_business_unit}= Query select id_company_business_unit from spy_company_business_unit where "key"='${business_unit_key}'
+ END
+ ${id_business_unit}= Evaluate ${id_business_unit[0][0]}+0
+ IF '${db_engine}' == 'pymysql'
+ ${id_company}= Query select id_company from spy_company WHERE `key`='${company_key}'
+ ELSE
+ ${id_company}= Query select id_company from spy_company WHERE "key"='${company_key}'
+ END
+ ${id_company}= Evaluate ${id_company[0][0]}+0
+ ${id_company_user}= Query select id_company_user from spy_company_user WHERE fk_customer=${id_customer} and fk_company_business_unit=${id_business_unit} and fk_company=${id_company}
+ ${id_company_user}= Evaluate ${id_company_user[0][0]}+0
+ ${id_company_role_admin}= Query select id_company_role from spy_company_role WHERE name='Admin' and fk_company='${id_company}'
+ ${id_company_role_admin}= Evaluate ${id_company_role_admin[0][0]}+0
+ ${is_role_set}= Query SELECT id_company_role_to_company_user FROM spy_company_role_to_company_user WHERE fk_company_role = ${id_company_role_admin} and fk_company_user = ${id_company_user}
+ ${is_role_set_length}= Get Length ${is_role_set}
+ IF ${is_role_set_length} == 0
+ ${last_id}= Query SELECT id_company_role_to_company_user FROM spy_company_role_to_company_user ORDER BY id_company_role_to_company_user DESC LIMIT 1;
+ ${new_id}= Evaluate ${last_id[0][0]}+1
+ Execute Sql String INSERT INTO spy_company_role_to_company_user (id_company_role_to_company_user, fk_company_role, fk_company_user) VALUES (${new_id}, ${id_company_role_admin}, ${id_company_user});
+ END
+ ${company_user_uuid}= Query select uuid from spy_company_user where id_company_user=${id_company_user}
+ ${company_user_uuid}= Convert To String ${company_user_uuid}
+ ${company_user_uuid}= Replace String ${company_user_uuid} ' ${EMPTY}
+ ${company_user_uuid}= Replace String ${company_user_uuid} , ${EMPTY}
+ ${company_user_uuid}= Replace String ${company_user_uuid} ( ${EMPTY}
+ ${company_user_uuid}= Replace String ${company_user_uuid} ) ${EMPTY}
+ ${company_user_uuid}= Replace String ${company_user_uuid} [ ${EMPTY}
+ ${company_user_uuid}= Replace String ${company_user_uuid} ] ${EMPTY}
+ Set Test Variable ${company_user_uuid} ${company_user_uuid}
+ Reset Log Level
+ RETURN ${company_user_uuid}
+
+Get voucher code by discountId from Database:
+ [Documentation] This keyword allows to get voucher code according to the discount ID. Discount_id can be found in Backoffice > Merchandising > Discount page
+ ... and set this id as an argument of a keyword.
+ ...
+ ... *Example:*
+ ... ``Get voucher code by discountId from Database: 3``
+ [Arguments] ${discount_id}
+ Save the result of a SELECT DB query to a variable: select fk_discount_voucher_pool from spy_discount where id_discount = ${discount_id} discount_voucher_pool_id
+ IF '${db_engine}' == 'pymysql'
+ Save the result of a SELECT DB query to a variable: select code from spy_discount_voucher where fk_discount_voucher_pool = ${discount_voucher_pool_id} and is_active = 1 limit 1 discount_voucher_code
+ ELSE
+ Save the result of a SELECT DB query to a variable: select code from spy_discount_voucher where fk_discount_voucher_pool = ${discount_voucher_pool_id} and is_active = true limit 1 discount_voucher_code
+ END
+
+Update dynamic entity configuration relation in Database:
+ [Documentation] This keyword update dynamic entity configuration in the DB tables spy_dynamic_entity_configuration_relation and spy_dynamic_entity_configuration_relation_field_mapping.
+ ... *Example:*
+ ...
+ ... ``Update dynamic entity configuration relation in Database: product-abstracts products productAbstractProducts fk_product_abstract id_product_abstract``
+ ...
+ [Arguments] ${parent_dynamic_entity_configuration_alias} ${child_dynamic_entity_configuration_alias} ${name} ${child_field_name} ${parent_field_name}
+ Connect to Spryker DB
+
+ ${parent_dynamic_entity_configuration_alias_id}= Query SELECT id_dynamic_entity_configuration from spy_dynamic_entity_configuration where table_alias='${parent_dynamic_entity_configuration_alias}';
+ ${parent_dynamic_entity_configuration_alias_id}= Set Variable ${parent_dynamic_entity_configuration_alias_id[0][0]}
+ Log ${parent_dynamic_entity_configuration_alias_id}
+ ${child_dynamic_entity_configuration_alias_id}= Query SELECT id_dynamic_entity_configuration from spy_dynamic_entity_configuration where table_alias='${child_dynamic_entity_configuration_alias}';
+ ${child_dynamic_entity_configuration_alias_id}= Set Variable ${child_dynamic_entity_configuration_alias_id[0][0]}
+ Log ${child_dynamic_entity_configuration_alias_id}
+ Execute Sql String update spy_dynamic_entity_configuration_relation set fk_parent_dynamic_entity_configuration = '${parent_dynamic_entity_configuration_alias_id}', fk_child_dynamic_entity_configuration = '${child_dynamic_entity_configuration_alias_id}', name = '${name}', is_editable = true where name='${name}';
+
+ ${dynamic_entity_configuration_relation_id}= Query SELECT id_dynamic_entity_configuration_relation from spy_dynamic_entity_configuration_relation where name='${name}';
+ ${dynamic_entity_configuration_relation_id}= Set Variable ${dynamic_entity_configuration_relation_id[0][0]}
+
+ Execute Sql String update spy_dynamic_entity_configuration_relation_field_mapping set parent_field_name = '${parent_field_name}', child_field_name = '${child_field_name}' where fk_dynamic_entity_configuration_relation='${dynamic_entity_configuration_relation_id}';
+ Disconnect From Database
+
+Create dynamic entity configuration in Database:
+ [Documentation] This keyword create dynamic entity configuration in the DB table spy_dynamic_entity_configuration.
+ ... *Example:*
+ ...
+ ... ``Create dynamic entity configuration in Database: country spy_country 1 {"identifier":"id_country","fields":[...]}``
+ ...
+ [Arguments] ${table_alias} ${table_name} ${is_active} ${definition}
+ ${new_id}= Get next id from table spy_dynamic_entity_configuration id_dynamic_entity_configuration
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_dynamic_entity_configuration (table_alias, table_name, is_active, definition) value ('${table_alias}', '${table_name}', '${is_active}', '${definition}');
+ ELSE
+ Execute Sql String insert into spy_dynamic_entity_configuration (id_dynamic_entity_configuration, table_alias, table_name, is_active, definition) values (${new_id}, '${table_alias}', '${table_name}', '${is_active}', '${definition}')
+ END
+ Disconnect From Database
+
+Delete dynamic entity configuration in Database:
+ [Documentation] This keyword delete dynamic entity configuration in the DB table spy_dynamic_entity_configuration.
+ ... *Example:*
+ ...
+ ... ``Delete dynamic entity configuration in Database: country```
+ ...
+ [Arguments] ${table_alias}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_dynamic_entity_configuration WHERE table_alias = '${table_alias}';
+ Disconnect From Database
+
+Create dynamic entity configuration relation in Database:
+ [Documentation] This keyword create dynamic entity configuration in the DB tables spy_dynamic_entity_configuration_relation and spy_dynamic_entity_configuration_relation_field_mapping.
+ ... *Example:*
+ ...
+ ... ``Create dynamic entity configuration relation in Database: country spy_country 1 {"identifier":"id_country","fields":[...]}``
+ ...
+ [Arguments] ${parent_dynamic_entity_configuration_alias} ${child_dynamic_entity_configuration_alias} ${name} ${child_field_name} ${parent_field_name}
+ Connect to Spryker DB
+
+ ${parent_dynamic_entity_configuration_alias_id}= Query SELECT id_dynamic_entity_configuration from spy_dynamic_entity_configuration where table_alias='${parent_dynamic_entity_configuration_alias}';
+ ${parent_dynamic_entity_configuration_alias_id}= Set Variable ${parent_dynamic_entity_configuration_alias_id[0][0]}
+ Log ${parent_dynamic_entity_configuration_alias_id}
+ ${child_dynamic_entity_configuration_alias_id}= Query SELECT id_dynamic_entity_configuration from spy_dynamic_entity_configuration where table_alias='${child_dynamic_entity_configuration_alias}';
+ ${child_dynamic_entity_configuration_alias_id}= Set Variable ${child_dynamic_entity_configuration_alias_id[0][0]}
+ Log ${child_dynamic_entity_configuration_alias_id}
+
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String INSERT INTO spy_dynamic_entity_configuration_relation (fk_parent_dynamic_entity_configuration,fk_child_dynamic_entity_configuration,name,is_editable) VALUES (${parent_dynamic_entity_configuration_alias_id},${child_dynamic_entity_configuration_alias_id},'${name}',true);
+ ELSE
+ Disconnect From Database
+ ${new_relation_id}= Get next id from table spy_dynamic_entity_configuration_relation id_dynamic_entity_configuration_relation
+ Log ${new_relation_id}
+ Connect to Spryker DB
+ Execute Sql String INSERT INTO spy_dynamic_entity_configuration_relation (id_dynamic_entity_configuration_relation, fk_parent_dynamic_entity_configuration, fk_child_dynamic_entity_configuration,name,is_editable) values (${new_relation_id}, ${parent_dynamic_entity_configuration_alias_id},${child_dynamic_entity_configuration_alias_id},'${name}',true);
+ END
+
+ ${dynamic_entity_configuration_relation_id}= Query SELECT id_dynamic_entity_configuration_relation from spy_dynamic_entity_configuration_relation where name='${name}';
+ ${dynamic_entity_configuration_relation_id}= Set Variable ${dynamic_entity_configuration_relation_id[0][0]}
+
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_dynamic_entity_configuration_relation_field_mapping (fk_dynamic_entity_configuration_relation, parent_field_name, child_field_name) value (${dynamic_entity_configuration_relation_id}, '${parent_field_name}', '${child_field_name}');
+ ELSE
+ Disconnect From Database
+ ${new_mapping_id}= Get next id from table spy_dynamic_entity_configuration_relation_field_mapping id_dynamic_entity_configuration_relation_field_mapping
+ Connect to Spryker DB
+ Execute Sql String insert into spy_dynamic_entity_configuration_relation_field_mapping (id_dynamic_entity_configuration_relation_field_mapping, fk_dynamic_entity_configuration_relation, parent_field_name, child_field_name) values (${new_mapping_id},'${dynamic_entity_configuration_relation_id}','${parent_field_name}','${child_field_name}');
+ END
+ Disconnect From Database
+
+Delete dynamic entity configuration relation in Database:
+ [Documentation] This keyword delete dynamic entity configuration in the DB table spy_dynamic_entity_configuration_relation.
+ ... *Example:*
+ ...
+ ... ``Delete dynamic entity configuration relation in Database: name```
+ ...
+ [Arguments] ${relation_name}
+ Connect to Spryker DB
+ ${dynamic_entity_configuration_relation_id}= Query SELECT id_dynamic_entity_configuration_relation from spy_dynamic_entity_configuration_relation where name='${relation_name}';
+ ${dynamic_entity_configuration_relation_id_length}= Get Length ${dynamic_entity_configuration_relation_id}
+ ${dynamic_entity_configuration_relation_id_length}= Set Variable ${dynamic_entity_configuration_relation_id_length}
+ IF ${dynamic_entity_configuration_relation_id_length} > 0
+ ${dynamic_entity_configuration_relation_id}= Set Variable ${dynamic_entity_configuration_relation_id[0][0]}
+ Log ${dynamic_entity_configuration_relation_id}
+
+ Execute Sql String DELETE FROM spy_dynamic_entity_configuration_relation_field_mapping WHERE fk_dynamic_entity_configuration_relation = ${dynamic_entity_configuration_relation_id};
+ Execute Sql String DELETE FROM spy_dynamic_entity_configuration_relation WHERE id_dynamic_entity_configuration_relation = ${dynamic_entity_configuration_relation_id};
+ END
+
+ Disconnect From Database
+
+Delete product by id_product in Database:
+ [Documentation] This keyword deletes a product by id_product in the DB table spy_product.
+ ... *Example:*
+ ...
+ ... ``Delete product by id_product in Database: 100``
+ ...
+ [Arguments] ${id_product}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_product WHERE id_product = ${id_product};
+ Disconnect From Database
+
+Delete product_abstract by id_product_abstract in Database:
+ [Documentation] This keyword deletes a product abstract by id_product_abstract from spy_product_abstract.
+ ... *Example:*
+ ...
+ ... ``Delete product_abstract by id_product_abstract in Database: 200``
+ ...
+ [Arguments] ${id_product_abstract}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_product_abstract WHERE id_product_abstract = ${id_product_abstract};
+ Disconnect From Database
+
+Delete complex product by id_product_abstract in Database:
+ [Documentation] This keyword deletes a product abstract by id_product_abstract from spy_product_abstract.
+ ... *Example:*
+ ...
+ ... ``Delete complex product by id_product_abstract in Database: 200``
+ ...
+ [Arguments] ${id_product_abstract}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_product_image_set WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_label_product_abstract WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_localized_attributes WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_url WHERE fk_resource_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_category WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_page_search WHERE fk_product_abstract = ${id_product_abstract};
+
+ ${id_price_product}= Query SELECT id_price_product from spy_price_product WHERE fk_product_abstract = ${id_product_abstract};
+ ${id_price_product_length}= Get Length ${id_price_product}
+ IF ${id_price_product_length} > 0
+ ${id_price_product}= Set Variable ${id_price_product[0][0]}
+ Execute Sql String DELETE FROM spy_price_product_store WHERE fk_price_product = ${id_price_product};
+ Execute Sql String DELETE FROM spy_price_product WHERE fk_product_abstract = ${id_product_abstract};
+ END
+
+ ${id_product_relation}= Query SELECT id_product_relation from spy_product_relation WHERE fk_product_abstract = ${id_product_abstract};
+ ${id_product_relation_length}= Get Length ${id_product_relation}
+ IF ${id_product_relation_length} > 0
+ ${id_product_relation}= Set Variable ${id_product_relation[0][0]}
+ Execute Sql String DELETE FROM spy_product_relation_store WHERE fk_product_relation = ${id_product_relation};
+ Execute Sql String DELETE FROM spy_product_relation WHERE fk_product_abstract = ${id_product_abstract};
+ END
+
+ ${id_product}= Query SELECT id_product from spy_product WHERE fk_product_abstract='${id_product_abstract}';
+ ${id_product_length}= Get Length ${id_product}
+ IF ${id_product_length} > 0
+ ${id_product}= Set Variable ${id_product[0][0]}
+ Execute Sql String DELETE FROM spy_product_search WHERE fk_product = ${id_product};
+ Execute Sql String DELETE FROM spy_stock_product WHERE fk_product = ${id_product};
+ Execute Sql String DELETE FROM spy_product_concrete_page_search WHERE fk_product = ${id_product};
+ Execute Sql String DELETE FROM spy_product_search WHERE fk_product = ${id_product};
+ Execute Sql String DELETE FROM spy_product_localized_attributes WHERE fk_product = ${id_product};
+ Execute Sql String DELETE FROM spy_product WHERE fk_product_abstract = ${id_product_abstract};
+ END
+
+ Execute Sql String DELETE FROM spy_product_abstract_store WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_category_storage WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_label_storage WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_product_list_storage WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_page_search WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_relation_storage WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract_storage WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_label_product_abstract WHERE fk_product_abstract = ${id_product_abstract};
+ Execute Sql String DELETE FROM spy_product_abstract WHERE id_product_abstract = ${id_product_abstract};
+
+ Disconnect From Database
+
+Delete product_price by id_price_product in Database:
+ [Documentation] This keyword deletes a product price by id_price_product from spy_price_product.
+ ... *Example:*
+ ...
+ ... ``Delete product_price by id_price_product in Database: 200``
+ ...
+ [Arguments] ${id_price_product}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_price_product WHERE id_price_product = ${id_price_product};
+ Disconnect From Database
+
+Trigger product labels update
+ [Arguments] ${timeout}=0.5s
+ Run console command console product-label:relations:update -vvv --no-touch DE
+ Run console command console product-label:validity DE
+ Run console command console product-label:relations:update -vvv --no-touch AT
+ Run console command console product-label:validity AT
+ Repeat Keyword 2 Trigger multistore p&s
+ IF ${docker} or ${ignore_console} != True Sleep ${timeout}
+
+Create dynamic admin user in DB
+ [Documentation] This keyword creates a new admin user in the DB using data from an existing admin.
+ ... It works for both MariaDB and PostgreSQL.
+ [Arguments] ${user_name}=${EMPTY} ${first_name}=Dynamic ${last_name}=Admin ${based_on}=${zed_admin_email}
+
+ IF '${user_name}' == '${EMPTY}'
+ ${unique}= Generate Random String 5 [NUMBERS]
+ VAR ${user_name} admin+robot${unique}@spryker.com
+ VAR ${dynamic_admin_user} ${user_name} scope=TEST
+ ELSE
+ VAR ${dynamic_admin_user} ${user_name} scope=TEST
+ END
+
+ # Step 1: Fetch the existing user data (admin@spryker.com)
+ Connect to Spryker DB
+ ${existing_user_data_id}= Query SELECT spy_user.id_user FROM spy_user WHERE username = '${based_on}'
+ ${existing_user_data_locale}= Query SELECT spy_user.fk_locale FROM spy_user WHERE username = '${based_on}'
+ ${existing_user_data_password}= Query SELECT spy_user.password FROM spy_user WHERE username = '${based_on}'
+ ${existing_user_data_created_at}= Query SELECT spy_user.created_at FROM spy_user WHERE username = '${based_on}'
+ ${existing_user_data_updated_at}= Query SELECT spy_user.updated_at FROM spy_user WHERE username = '${based_on}'
+
+ # Step 1: Extract fields from the existing user
+ ${existing_id_user}= Set Variable ${existing_user_data_id[0][0]}
+ ${existing_fk_locale}= Set Variable ${existing_user_data_locale[0][0]}
+ ${existing_password}= Set Variable ${existing_user_data_password[0][0]}
+ ${existing_created_at}= Set Variable ${existing_user_data_created_at[0][0]}
+ ${existing_updated_at}= Set Variable ${existing_user_data_updated_at[0][0]}
+
+ # Step 2: Get the maximum id_user and increment it
+ ${max_id_user}= Query SELECT MAX(id_user) FROM spy_user
+ IF '${None}' in '${max_id_user}' VAR ${max_id_user} 0
+
+ IF ${max_id_user[0][0]} > 5000
+ # new ID will be max +1 not to intersect with real IDs
+ ${new_id_user}= Evaluate ${max_id_user[0][0]} + 1
+ ELSE
+ # new ID will be max + 5001 not to intersect with real IDs
+ ${new_id_user}= Evaluate ${max_id_user[0][0]} + 5001
+ END
+ # Step 3: Generate new UUID
+ ${new_uuid}= Generate Random String 4 [UPPER]
+ VAR ${new_uuid} ${new_uuid}-${random}-${random_str}-${random_id}
+
+ # Step 4: Check table structure before the insert
+
+ IF '${db_engine}' == 'pymysql'
+ ${spy_user_column_names}= Query SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'spy_user' AND TABLE_SCHEMA = DATABASE()
+ ${spy_user_column_names}= Convert To String ${spy_user_column_names}
+ ${is_uuid_present}= Run Keyword And Return Status Should Contain ${spy_user_column_names} uuid
+ VAR ${is_uuid_present} ${is_uuid_present}
+ ELSE
+ ${spy_user_column_names}= Query SELECT column_name FROM information_schema.columns WHERE table_name = 'spy_user' AND table_schema = current_schema
+ ${spy_user_column_names}= Convert To String ${spy_user_column_names}
+ ${is_uuid_present}= Run Keyword And Return Status Should Contain ${spy_user_column_names} uuid
+ VAR ${is_uuid_present} ${is_uuid_present}
+ END
+
+ # Step 5: Insert the new user into the spy_user table using correct variables
+ ${attempt}= Set Variable 1
+ WHILE ${attempt} <= 3
+ TRY
+ IF ${is_uuid_present}
+ Execute Sql String INSERT INTO spy_user (id_user, fk_locale, is_agent, first_name, last_name, password, status, username, uuid, created_at, updated_at) VALUES (${new_id_user}, ${existing_fk_locale}, True, '${first_name}', '${last_name}', '${existing_password}', 0, '${user_name}', '${new_uuid}', '${existing_created_at}', '${existing_updated_at}')
+ ELSE
+ Execute Sql String INSERT INTO spy_user (id_user, fk_locale, is_agent, first_name, last_name, password, status, username, created_at, updated_at) VALUES (${new_id_user}, ${existing_fk_locale}, True, '${first_name}', '${last_name}', '${existing_password}', 0, '${user_name}', '${existing_created_at}', '${existing_updated_at}')
+ END
+ Exit For Loop
+ EXCEPT
+ Log Attempt ${attempt} failed due to duplicate entry in spy_user. Retrying...
+ ${unique_id}= Generate Random String 3 [NUMBERS]
+ ${unique_id}= Replace String ${unique_id} 0 9
+ ${unique_id}= Convert To Integer ${unique_id}
+ ${new_id_user}= Evaluate ${new_id_user} + ${unique_id}
+ ${unique}= Generate Random String 5 [NUMBERS]
+ VAR ${new_uuid} ${unique}-${random}-${random_str}-${random_id}
+ IF '${user_name}' == '${EMPTY}'
+ VAR ${user_name} admin+robot${unique}@spryker.com
+ VAR ${dynamic_admin_user} ${user_name} scope=TEST
+ END
+ ${attempt}= Evaluate ${attempt} + 1
+ END
+ END
+ IF ${attempt} > 3 Fail Unable to insert user into spy_users after 3 attempts.
+
+ # Step 6: Get the ACL group of the existing user from spy_acl_user_has_group
+ ${existing_acl_group}= Query SELECT fk_acl_group FROM spy_acl_user_has_group WHERE fk_user = ${existing_id_user}
+
+ # Step 7: Insert the new user’s ID and the same ACL group into spy_acl_user_has_group
+ Execute Sql String INSERT INTO spy_acl_user_has_group (fk_user, fk_acl_group) VALUES (${new_id_user}, ${existing_acl_group[0][0]})
+
+ Disconnect From Database
+
+Delete dynamic admin user from DB
+ [Documentation] This keyword deletes a dynamic admin user from the DB based on the provided username.
+ ... It works for both MariaDB and PostgreSQL.
+ [Arguments] ${user_name}=${EMPTY}
+
+ ${dynamic_admin_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+
+ # Step 2: Decide action based on existence of discount states and the argument
+
+ IF '${user_name}' == '${EMPTY}'
+ IF ${dynamic_admin_exists}
+ VAR ${user_name} ${dynamic_admin_user}
+ ELSE
+ Log message=No dynamic (doesn't exist) or static user was provided for deletion level=INFO
+ RETURN
+ END
+ END
+
+ # Step 1: Fetch the ID of the user to be deleted
+ Connect to Spryker DB
+ ${user_data}= Query SELECT id_user FROM spy_user WHERE username = '${user_name}'
+ ${user_exists}= Evaluate len(${user_data}) > 0
+
+ IF ${user_exists}
+ ${user_id}= Set Variable ${user_data[0][0]}
+
+ # Step 2: Delete entries in related tables
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String DELETE FROM spy_acl_user_has_group WHERE fk_user = ${user_id}
+ ELSE
+ Execute Sql String DELETE FROM spy_acl_user_has_group WHERE fk_user = ${user_id}
+ END
+
+ # Step 3: Delete the user from spy_user table
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String DELETE FROM spy_user WHERE id_user = ${user_id}
+ ELSE
+ Execute Sql String DELETE FROM spy_user WHERE id_user = ${user_id}
+ END
+ END
+
+ Disconnect From Database
+
+Create dynamic customer in DB
+ [Documentation] This keyword creates a new approved dynamic customer in the DB based on an existing customer (sonia@spryker.com) and assigns the customer to a company.
+ ... It works for both MariaDB and PostgreSQL.
+ [Arguments] ${first_name}=Dynamic ${last_name}=Customer ${email}=${EMPTY} ${based_on}=${EMPTY} ${create_default_address}=True
+ ${dynamic_customer_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_customer}
+ ${dynamic_second_customer_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_second_customer}
+
+ IF '${email}' == '${EMPTY}'
+ ${unique}= Generate Random String 5 [NUMBERS]
+ IF ${dynamic_second_customer_exists}
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_third_customer} ${email} scope=TEST
+ ELSE IF ${dynamic_customer_exists}
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_second_customer} ${email} scope=TEST
+ ELSE
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_customer} ${email} scope=TEST
+ END
+ END
+
+ IF '${based_on}' == '${EMPTY}'
+ VAR ${based_on} sonia@spryker.com
+ END
+
+ # Step 1: Fetch the existing customer data (${based_on})
+ Connect to Spryker DB
+ ${existing_customer_data}= Query SELECT * FROM spy_customer WHERE email = '${based_on}'
+
+ # Extract all columns from the existing customer with Set Variable If for conditional handling of None values
+ VAR ${existing_customer_id} ${existing_customer_data[0][0]}
+ ${existing_fk_locale}= Set Variable If ${existing_customer_data[0][1]} ${existing_customer_data[0][1]} NULL
+ ${existing_fk_user}= Set Variable If ${existing_customer_data[0][2]} ${existing_customer_data[0][2]} NULL
+ ${existing_anonymized_at}= Set Variable If ${existing_customer_data[0][3]} ${existing_customer_data[0][3]} NULL
+ ${existing_company}= Set Variable If '${existing_customer_data[0][4]}' != '${EMPTY}' ${existing_customer_data[0][4]} ${EMPTY}
+ ${existing_date_of_birth}= Set Variable If ${existing_customer_data[0][6]} ${existing_customer_data[0][6]} NULL
+ VAR ${existing_default_billing_address} NULL
+ VAR ${existing_default_shipping_address} NULL
+ ${existing_gender}= Set Variable If ${existing_customer_data[0][11]} ${existing_customer_data[0][11]} NULL
+ ${existing_password}= Set Variable ${existing_customer_data[0][13]}
+ ${existing_phone}= Set Variable If '${existing_customer_data[0][14]}' != '${EMPTY}' ${existing_customer_data[0][14]} ${EMPTY}
+ ${existing_registered}= Set Variable If ${existing_customer_data[0][15]} ${existing_customer_data[0][15]} '2020-06-24'
+ ${existing_registration_key}= Set Variable If ${existing_customer_data[0][16]} ${existing_customer_data[0][16]} NULL
+ VAR ${existing_restore_password_date} NULL
+ VAR ${existing_restore_password_key} NULL
+ ${existing_salutation}= Set Variable ${existing_customer_data[0][19]}
+ ${existing_created_at}= Set Variable ${existing_customer_data[0][20]}
+ ${existing_updated_at}= Set Variable ${existing_customer_data[0][21]}
+
+ # Step 2: Get the maximum id_customer and increment it
+ ${max_id_customer}= Query SELECT MAX(id_customer) FROM spy_customer
+ IF '${None}' in '${max_id_customer}' VAR ${max_id_customer} 0
+
+ IF ${max_id_customer[0][0]} > 5000
+ # new ID will be max +1 not to intersect with real IDs
+ ${new_id_customer}= Evaluate ${max_id_customer[0][0]} + 1
+ ELSE
+ # new ID will be max + 5001 not to intersect with real IDs
+ ${new_id_customer}= Evaluate ${max_id_customer[0][0]} + 5001
+ END
+
+ # Step 3: Generate new values for customer_reference
+ ${new_customer_reference}= Set Variable dynamic--${new_id_customer}
+
+ # Step 4: Insert the new customer into the spy_customer table using all columns
+ ${attempt}= Set Variable 1
+ WHILE ${attempt} <= 3
+ TRY
+ Execute Sql String INSERT INTO spy_customer (id_customer, fk_locale, fk_user, anonymized_at, company, customer_reference, date_of_birth, default_billing_address, default_shipping_address, email, first_name, gender, last_name, password, phone, registered, registration_key, restore_password_date, restore_password_key, salutation, created_at, updated_at) VALUES (${new_id_customer}, ${existing_fk_locale}, ${existing_fk_user}, ${existing_anonymized_at}, '${existing_company}', '${new_customer_reference}', ${existing_date_of_birth}, ${existing_default_billing_address}, ${existing_default_shipping_address}, '${email}', '${first_name}', ${existing_gender}, '${last_name}', '${existing_password}', '${existing_phone}', '${existing_registered}', ${existing_registration_key}, ${existing_restore_password_date}, ${existing_restore_password_key}, ${existing_salutation}, '${existing_created_at}', '${existing_updated_at}')
+ Exit For Loop
+ EXCEPT
+ Log Attempt ${attempt} failed due to duplicate entry in spy_customer. Retrying...
+ ${unique_id}= Generate Random String 3 [NUMBERS]
+ ${unique_id}= Replace String ${unique_id} 0 9
+ ${unique_id}= Convert To Integer ${unique_id}
+ ${new_id_customer}= Evaluate ${new_id_customer} + ${unique_id}
+ ${new_customer_reference}= Set Variable dynamic--${new_id_customer}
+ IF '${email}' == '${EMPTY}' or 'sonia+robot' in '${email}'
+ ${unique}= Generate Random String 5 [NUMBERS]
+ IF ${dynamic_second_customer_exists}
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_third_customer} ${email} scope=TEST
+ ELSE IF ${dynamic_customer_exists}
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_second_customer} ${email} scope=TEST
+ ELSE
+ VAR ${email} sonia+robot${unique}@spryker.com
+ VAR ${dynamic_customer} ${email} scope=TEST
+ END
+ END
+ ${attempt}= Evaluate ${attempt} + 1
+ END
+ END
+ IF ${attempt} > 3 Fail Unable to insert customer into spy_customer after 3 attempts.
+
+ IF '${env}' in ['ui_b2b','ui_mp_b2b','ui_suite']
+ # Step 5: Fetch the existing company user data associated with the existing customer
+ ${existing_company_user_data}= Query SELECT * FROM spy_company_user WHERE fk_customer = ${existing_customer_id}
+ ${existing_company_user_data_length}= Get Length ${existing_company_user_data}
+ IF ${existing_company_user_data_length} > 0
+ # Extract the relevant fields for inserting a new company user
+ VAR ${existing_id_company_user} ${existing_company_user_data[0][0]}
+ VAR ${existing_fk_company} ${existing_company_user_data[0][1]}
+ VAR ${existing_fk_company_business_unit} ${existing_company_user_data[0][2]}
+ VAR ${existing_key} ${existing_company_user_data[0][6]}
+
+ # Step 6: Get the maximum id_company_user and increment it
+ ${max_id_company_user}= Query SELECT MAX(id_company_user) FROM spy_company_user
+ IF '${None}' in '${max_id_company_user}' VAR ${max_id_company_user} 0
+
+ IF ${max_id_company_user[0][0]} > 5000
+ # new ID will be max +1 not to intersect with real IDs
+ ${new_id_company_user}= Evaluate ${max_id_company_user[0][0]} + 1
+ ELSE
+ # new ID will be max + 5001 not to intersect with real IDs
+ ${new_id_company_user}= Evaluate ${max_id_company_user[0][0]} + 5001
+ END
+
+ # Step 7: Generate unique values for `key` and `uuid`
+ VAR ${new_key} ${existing_key}--${new_id_company_user}
+ ${new_uuid}= Generate Random String 4 [UPPER]
+ VAR ${new_uuid} ${new_uuid}-${random}-${random_str}-${random_id}
+
+ # Step 8: Insert the new company user entry in the spy_company_user table
+ ${attempt}= Set Variable 1
+ WHILE ${attempt} <= 3
+ TRY
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String INSERT INTO spy_company_user (id_company_user, fk_company, fk_company_business_unit, fk_customer, is_active, is_default, \`key\`, uuid) VALUES (${new_id_company_user}, ${existing_fk_company}, ${existing_fk_company_business_unit}, ${new_id_customer}, True, False, '${new_key}', '${new_uuid}')
+ ELSE
+ Execute Sql String INSERT INTO spy_company_user (id_company_user, fk_company, fk_company_business_unit, fk_customer, is_active, is_default, key, uuid) VALUES (${new_id_company_user}, ${existing_fk_company}, ${existing_fk_company_business_unit}, ${new_id_customer}, True, False, '${new_key}', '${new_uuid}')
+ END
+ Exit For Loop
+ EXCEPT
+ Log Attempt ${attempt} failed due to duplicate entry in spy_company_user. Retrying...
+ ${unique_id}= Generate Random String 3 [NUMBERS]
+ ${unique_id}= Replace String ${unique_id} 0 9
+ ${unique_id}= Convert To Integer ${unique_id}
+ ${new_id_company_user}= Evaluate ${new_id_company_user} + ${unique_id}
+ ${new_key}= Set Variable ${existing_key}--${new_id_company_user}
+ ${unique}= Generate Random String 5 [NUMBERS]
+ VAR ${new_uuid} ${unique}-${random}-${random_str}-${random_id}
+ ${attempt}= Evaluate ${attempt} + 1
+ END
+ END
+ IF ${attempt} > 3 Fail Unable to insert company user into spy_company_user after 3 attempts.
+
+ # Insert the new company role to company user entry in the spy_company_role_to_company_user table
+ ${existing_company_role_to_user_data}= Query SELECT * FROM spy_company_role_to_company_user WHERE fk_company_user = ${existing_id_company_user}
+ FOR ${roles} IN @{existing_company_role_to_user_data}
+
+ VAR ${existing_fk_company_role} ${roles[1]}
+ VAR ${existing_created_at} ${roles[3]}
+ VAR ${existing_updated_at} ${roles[4]}
+
+ # Get the maximum id_company_role_to_company_user and increment it
+ ${max_id_company_role_to_company_user}= Query SELECT MAX(id_company_role_to_company_user) FROM spy_company_role_to_company_user
+ IF '${None}' in '${max_id_company_role_to_company_user}' VAR ${max_id_company_role_to_company_user} 0
+
+ IF ${max_id_company_role_to_company_user[0][0]} > 5000
+ # new ID will be max +1 not to intersect with real IDs
+ ${new_id_company_role_to_company_user}= Evaluate ${max_id_company_role_to_company_user[0][0]} + 1
+ ELSE
+ # new ID will be max + 5001 not to intersect with real IDs
+ ${new_id_company_role_to_company_user}= Evaluate ${max_id_company_role_to_company_user[0][0]} + 5001
+ END
+
+ # Insert the new company role to company user entry in the spy_company_role_to_company_user table
+ ${attempt}= Set Variable 1
+ WHILE ${attempt} <= 3
+ TRY
+ Execute Sql String INSERT INTO spy_company_role_to_company_user (id_company_role_to_company_user, fk_company_role, fk_company_user, created_at, updated_at) VALUES (${new_id_company_role_to_company_user}, ${existing_fk_company_role}, ${new_id_company_user}, '${existing_created_at}', '${existing_updated_at}')
+ Exit For Loop
+ EXCEPT
+ Log Attempt ${attempt} failed due to duplicate entry in spy_company_role_to_company_user. Retrying...
+ ${unique_id}= Generate Random String 3 [NUMBERS]
+ ${unique_id}= Replace String ${unique_id} 0 9
+ ${unique_id}= Convert To Integer ${unique_id}
+ ${new_id_company_role_to_company_user}= Evaluate ${new_id_company_role_to_company_user} + ${unique_id}
+ ${attempt}= Evaluate ${attempt} + 1
+ END
+ END
+ IF ${attempt} > 3 Fail Unable to insert company role to company user into spy_company_role_to_company_user after 3 attempts.
+ END
+ ELSE
+ Log message=Selected customer is not a company user. Skipping company user creation. level=INFO
+ END
+ END
+
+ IF ${create_default_address}
+ # Step 9: Check if an address exists for the new customer
+ ${address_exists}= Query SELECT COUNT(*) FROM spy_customer_address WHERE fk_customer = ${new_id_customer}
+
+ # Step 10: Handle address creation or update
+ IF ${address_exists[0][0]} == 0
+ # No address exists, so create a new address
+ ${max_id_customer_address}= Query SELECT MAX(id_customer_address) FROM spy_customer_address
+ IF '${None}' in '${max_id_customer_address}' VAR ${max_id_customer_address} 0
+ IF ${max_id_customer_address[0][0]} > 5000
+ # new ID will be max +1 not to intersect with real IDs
+ ${new_id_customer_address}= Evaluate ${max_id_customer_address[0][0]} + 1
+ ELSE
+ # new ID will be max + 5001 not to intersect with real IDs
+ ${new_id_customer_address}= Evaluate ${max_id_customer_address[0][0]} + 5001
+ END
+ ${address_uuid}= Generate Random String 4 [UPPER]
+ VAR ${address_uuid} ${address_uuid}-${random}-${random_str}-${random_id}
+ ${attempt}= Set Variable 1
+ WHILE ${attempt} <= 3
+ TRY
+ Execute Sql String INSERT INTO spy_customer_address (id_customer_address, fk_country, fk_customer, fk_region, address1, address2, address3, anonymized_at, city, comment, company, deleted_at, first_name, last_name, phone, salutation, uuid, zip_code, created_at, updated_at) VALUES (${new_id_customer_address}, 60, ${new_id_customer}, NULL, '${default_address.street}', '${default_address.house_number}', NULL, NULL, '${default_address.city}', NULL, NULL, NULL, '${default_address.first_name}', '${default_address.last_name}', NULL, 0, '${address_uuid}', '${default_address.post_code}', NOW(), NOW())
+ Exit For Loop
+ EXCEPT
+ Log Attempt ${attempt} failed due to duplicate entry in spy_customer_address. Retrying...
+ ${unique_id}= Generate Random String 3 [NUMBERS]
+ ${unique_id}= Replace String ${unique_id} 0 9
+ ${unique_id}= Convert To Integer ${unique_id}
+ ${new_id_customer_address}= Evaluate ${new_id_customer_address} + ${unique_id}
+ ${unique}= Generate Random String 5 [NUMBERS]
+ VAR ${address_uuid} ${unique}-${random}-${random_str}-${random_id}
+ ${attempt}= Evaluate ${attempt} + 1
+ END
+ END
+ IF ${attempt} > 3 Fail Unable to insert customer address into spy_customer_address after 3 attempts.
+ ELSE
+ # Address exists, so update it
+ ${existing_address_id}= Query SELECT id_customer_address FROM spy_customer_address WHERE fk_customer = ${new_id_customer}
+ Execute Sql String UPDATE spy_customer_address SET fk_country = 60, fk_region = NULL, address1 = '${default_address.street}', address2 = '${default_address.house_number}', address3 = NULL, anonymized_at = NULL, city = '${default_address.city}', first_name = '${default_address.first_name}', last_name = '${default_address.last_name}', phone = NULL, salutation = 0, zip_code = '${default_address.post_code}', updated_at = NOW() WHERE id_customer_address = ${existing_address_id[0][0]}
+ END
+ END
+ Disconnect From Database
+
+Deactivate all discounts in the database
+ [Documentation] This keyword retrieves all existing discounts in the database, saves their keys and activation status,
+ ... and then sets each discount's `is_active` status to `False`.
+
+ # Step 1: Fetch all existing discounts
+ Connect to Spryker DB
+ ${existing_discounts}= Query SELECT discount_key, is_active FROM spy_discount
+
+ # Step 2: Store the current discount states with scope TEST
+ VAR ${discount_states} ${existing_discounts} scope=TEST
+
+ # Step 3: Deactivate all discounts
+ Execute Sql String UPDATE spy_discount SET is_active = False
+
+ Disconnect From Database
+
+Restore all discounts in the database
+ [Documentation] This keyword restores the activation status of all discounts based on the previously saved data.
+ ... It must be called after `Deactivate all discounts in the database` to ensure data is available for restoration.
+ [Arguments] ${enable_all_if_no_previous_state}=True
+
+ # Step 1: Check if discount states were saved
+ ${state_exists}= Run Keyword And Return Status Variable Should Exist ${discount_states}
+
+ # Step 2: Decide action based on existence of discount states and the argument
+ IF ${state_exists}
+ Log Restoring each discount's original state based on saved data.
+ Connect to Spryker DB
+ FOR ${discount_data} IN @{discount_states}
+ ${discount_key}= Set Variable ${discount_data[0]}
+ ${status}= Set Variable ${discount_data[1]}
+ Execute Sql String UPDATE spy_discount SET is_active = ${status} WHERE discount_key = '${discount_key}'
+ END
+ Disconnect From Database
+ ELSE
+ Log No saved discount state data available.
+ IF ${enable_all_if_no_previous_state}
+ Log Enabling all discounts as per the argument.
+ Connect to Spryker DB
+ Execute Sql String UPDATE spy_discount SET is_active = True
+ Disconnect From Database
+ ELSE
+ Fail No saved discount state data available and 'enable_all_if_no_previous_state' is set to False. Cannot proceed.
+ END
+ END
diff --git a/atest/testdata/performance/resources/common/common_api.robot b/atest/testdata/performance/resources/common/common_api.robot
new file mode 100644
index 0000000..1ff6239
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common_api.robot
@@ -0,0 +1,2540 @@
+*** Settings ***
+Library RequestsLibrary
+Library JSONLibrary
+Library ../../resources/libraries/fastjson.py
+Resource common.robot
+
+*** Variables ***
+# *** API SUITE VARIABLES ***
+${api_timeout} 15
+${max_retries} 0
+${default_password} change123
+${default_secure_password} qweRTY_123456
+${default_allow_redirects} true
+${default_auth} ${NONE}
+&{default_headers}
+${api_session} api
+
+# *** default headers example: applied to all requests if not empty ***
+# &{default_headers} Store=DE Accept-Language=EN
+
+# *** API VARIABLES ***
+${glue_env}
+${bapi_env}
+${sapi_env}
+
+*** Keywords ***
+API_suite_setup
+ [Documentation] Basic steps before each suite. Should be sed with the ``Suite Setup`` tag.
+ ...
+ ... *Example:*
+ ...
+ ... ``Suite Setup API_suite_setup``
+ Common_suite_setup skip_if_already_executed=${True}
+
+Overwrite api variables
+ Log Many @{Test Tags}
+ VAR ${current_url} ${EMPTY}
+ FOR ${tag} IN @{Test Tags}
+ Set Test Variable ${tag}
+ IF '${tag}' == 'dms-on' CONTINUE
+ IF '${glue_env}' == '${EMPTY}'
+ IF '${tag}' == 'glue'
+ IF ${dms}
+ Set Suite Variable ${current_url} ${glue_dms_url}
+ ELSE
+ Set Suite Variable ${current_url} ${glue_url}
+ END
+ Set Suite Variable ${tag} glue
+ END
+ ELSE
+ IF '${tag}' == 'glue'
+ Set Suite Variable ${current_url} ${glue_env}
+ Set Suite Variable ${tag} glue
+ END
+ END
+ IF '${bapi_env}' == '${EMPTY}'
+ IF '${tag}'=='bapi'
+ IF ${dms}
+ Set Suite Variable ${current_url} ${bapi_dms_url}
+ ELSE
+ Set Suite Variable ${current_url} ${bapi_url}
+ END
+ Set Suite Variable ${tag} bapi
+ END
+ ELSE
+ IF '${tag}' == 'bapi'
+ Set Suite Variable ${current_url} ${bapi_env}
+ Set Suite Variable ${tag} bapi
+ END
+ END
+ IF '${sapi_env}' == '${EMPTY}'
+ IF '${tag}' == 'sapi'
+ IF ${dms}
+ Set Suite Variable ${current_url} ${sapi_dms_url}
+ ELSE
+ Set Suite Variable ${current_url} ${sapi_url}
+ END
+ Set Suite Variable ${tag} sapi
+ END
+ ELSE
+ IF '${tag}' == 'sapi'
+ Set Suite Variable ${current_url} ${sapi_env}
+ Set Suite Variable ${tag} sapi
+ END
+ END
+ ${current_url_last_character}= Get Regexp Matches ${current_url} .$ flags=IGNORECASE
+ ${current_url_last_character}= Convert To String ${current_url_last_character}
+ ${current_url_last_character}= Replace String ${current_url_last_character} ' ${EMPTY}
+ ${current_url_last_character}= Replace String ${current_url_last_character} [ ${EMPTY}
+ ${current_url_last_character}= Replace String ${current_url_last_character} ] ${EMPTY}
+ IF '${current_url_last_character}' == '/'
+ ${current_url}= Replace String Using Regexp ${current_url} .$ ${EMPTY}
+ Set Suite Variable ${current_url}
+ END
+ END
+ Create Session ${api_session} ${current_url} timeout=${api_timeout} max_retries=${max_retries}
+
+Setup_api_host_if_undefined
+ ${api_host_is_undefined}= Run Keyword And Return Status Variable Should Not Exist ${current_url}
+ IF ${api_host_is_undefined} Overwrite api variables
+
+API_test_setup
+ [Documentation] This setup should be called in Settings of every test suite. It defines which url variable will be used in the test suite.
+ ...
+ ... At the moment it is used to define if the test is for GLUE (``glue`` tag) or BAPI (``bapi`` tag) by checking for the default or test tag.
+ ... If the tag is there it replaces the domein URL with bapi url.
+ ...
+ ... To set a tag to a test case use ``[Tags]`` under the test name.
+ ... To set Test Tags for the whole test suite (.robotframework file), use ``Test Tags`` keyword in the suite Settings.
+ ...
+ ... *Notes*:
+ ...
+ ... 1. If a test suite has no Test Setup and/or tests in the suite have no bapi/glue tags, GLUE URL will be used by default as the current URL.
+ ...
+ ... 2. Do not set both tags to a suite, each suite/robot file should have tests only for GLUE or only for BAPI.
+ ...
+ ... 3. You can set other tags for tests and suites with no restrictions, they will be ignored in suite setup.
+ ...
+ ... *Example:*
+ ...
+ ... ``*** Settings ***``
+ ...
+ ... ``Test Setup TestSetup``
+ ...
+ ... ``Test Tags bapi``
+ Should Test Run
+ Overwrite api variables
+ I set default Headers: &{default_headers}
+
+I set Headers:
+ [Documentation] Keyword sets any number of headers for the further endpoint calls.
+ ... Headers can have any name and any value, they are set as test variable - which means they can be used throughtout one test if set once.
+ ... This keyword can be used to add access token to the next endpoint calls or to set header for the guest customer, etc.
+ ...
+ ... It accepts a list of pairs haader-name=header-value as an argument. The list items should be separated by 4 spaces.
+ ...
+ ... *Example:*
+ ...
+ ... ``I set Headers: Content-Type=${default_header_content_type} Authorization=${token}``
+
+ [Arguments] &{headers}
+ Set To Dictionary ${headers} &{headers} &{default_headers}
+ Set Test Variable &{headers}
+ RETURN &{headers}
+
+Reset API Headers
+ [Documentation] This keyword resets all previously set headers to their default values.
+ ... It can be used to ensure that no unwanted headers persist between API requests.
+ ...
+ ... *Example:*
+ ...
+ ... ``I Reset Headers``
+
+ # Clear previously set headers
+ ${headers}= Create Dictionary
+
+ # Reapply default headers if needed
+ Set To Dictionary ${headers} &{default_headers}
+ Log Default headers have been restored.
+
+ # Re-register headers as a test variable
+ Set Test Variable &{headers}
+ RETURN &{headers}
+
+I set default Headers:
+ [Arguments] &{headers}
+ Set Suite Variable &{headers}
+ RETURN &{headers}
+
+I get access token for the customer:
+ [Documentation] This is a helper keyword which helps get access token for future use in the headers of the following requests.
+ ...
+ ... It gets the token for the specified customer ``{email}`` and saves it into the test variable ``{token}``, which can then be used within the scope of the test where this keyword was called.
+ ... After the test ends the ``{token}`` variable is cleared. This keyword needs to be called separately for each test where you expect to need a customer token.
+ ...
+ ... The password in this case is not passed to the keyword and the default password stored in ``{default_password}`` will be used when getting token.
+ ...
+ ... *Example:*
+ ...
+ ... ``I get access token for the customer: ${yves_user.email}``
+ [Arguments] ${email} ${password}=${default_password}
+ Setup_api_host_if_undefined
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${data}= Convert String To JSON {"data":{"type":"access-tokens","attributes":{"username":"${email}","password":"${password}"}}}
+ ${response}= IF ${headers_not_empty} POST On Session ${api_session} ${current_url}/access-tokens json=${data} headers=${headers} verify=${verify_ssl}
+ ... ELSE POST On Session ${api_session} ${current_url}/access-tokens json=${data} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${token}= Set Variable Bearer ${response.json()['data']['attributes']['accessToken']}
+ ${response_headers}= Set Variable ${response.headers}
+ Set Test Variable ${token} ${token}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${expected_self_link} ${current_url}/access-tokens
+ RETURN ${token}
+
+I get access token for the company user by uuid:
+ [Documentation] This is a helper keyword which helps get company user access token by uuid for future use in the headers of the following requests.
+ ...
+ ... It gets the token for the specified company user by ``{company_user_uuid}`` and saves it into the test variable ``{token}``, which can then be used within the scope of the test where this keyword was called.
+ ... After the test ends the ``{token}`` variable is cleared. This keyword needs to be called separately for each test where you expect to need a company user token.
+ ...
+ ... *Example:*
+ ...
+ ... ``I get access token for the company user by uuid: ${company_user_uuid}``
+ [Arguments] ${company_user_uuid}
+ Setup_api_host_if_undefined
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${data}= Convert String To JSON {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user_uuid}"}}}
+ ${response}= IF ${headers_not_empty} POST On Session ${api_session} ${current_url}/company-user-access-tokens json=${data} headers=${headers} verify=${verify_ssl}
+ ... ELSE POST On Session ${api_session} ${current_url}/company-user-access-tokens json=${data} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${token}= Set Variable Bearer ${response.json()['data']['attributes']['accessToken']}
+ ${response_headers}= Set Variable ${response.headers}
+ Set Test Variable ${token} ${token}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${expected_self_link} ${current_url}/company-user-access-tokens
+ RETURN ${token}
+
+I send a POST request:
+ [Documentation] This keyword is used to make POST requests. It accepts the endpoint *without the domain* and the body in JOSN.
+ ... Variables can and should be used in the endpoint url and in the body JSON.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}``
+ [Arguments] ${path} ${json} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Convert String To JSON ${json}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} POST On Session ${api_session} ${current_url}${path} json=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE POST On Session ${api_session} ${current_url}${path} json=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=ANY verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a POST request with data:
+ [Documentation] This keyword is used to make POST requests with a plain text data. It accepts the endpoint *without the domain* and the body in plain text.
+ ... Variables can and should be used in the endpoint url and in the body.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a POST request: /agent-access-tokens This is plain text body``
+ [Arguments] ${path} ${data} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Evaluate ${data}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} POST On Session ${api_session} ${current_url}${path} data=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE POST On Session ${api_session} ${current_url}${path} data=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a PUT request:
+ [Documentation] This keyword is used to make PUT requests. It accepts the endpoint *without the domain* and the body in JSON.
+ ... Variables can and should be used in the endpoint url and in the body JSON.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a PUT request: /some-endpoint/${someID} {"data": {"type": "some-type"}}``
+ [Arguments] ${path} ${json} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Convert String To JSON ${json}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} PUT On Session ${api_session} ${current_url}${path} json=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE PUT On Session ${api_session} ${current_url}${path} json=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a PUT request with data:
+ [Documentation] This keyword is used to make PUT requests with a plain text data. It accepts the endpoint *without the domain* and the body in plain text.
+ ... Variables can and should be used in the endpoint url and in the body plain text.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a PUT request: /some-endpoint/${someID} This is plain text body``
+ [Arguments] ${path} ${data} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Evaluate ${data}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} PUT On Session ${api_session} ${current_url}${path} data=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE PUT On Session ${api_session} ${current_url}${path} data=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a PATCH request:
+ [Documentation] This keyword is used to make PATCH requests. It accepts the endpoint *without the domain* and the body in JOSN.
+ ... Variables can and should be used in the endpoint url and in the body JSON.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ... If this keyword was already called within this test case (e.g. before POST request), there is no need to call it again.
+ ...
+ ... Usually for PATCH requests you need to know and use the ID (UID) if the resource you need to update.
+ ... To get the ID you need forst to make a POST or GET request to get the data and then call ``Save value to a variable:`` endpoint to save the ID to a test variable to be able to use it in the PATCH request.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a PATCH request: /carts/${cartUID}/items/${itemUID} {"data": {"type": "items","attributes": {"quantity": 5}}}``
+
+ [Arguments] ${path} ${json} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Convert String To JSON ${json}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} PATCH On Session ${api_session} ${current_url}${path} json=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE PATCH On Session ${api_session} ${current_url}${path} json=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a PATCH request with data:
+ [Documentation] This keyword is used to make PATCH requests with a plain text data. It accepts the endpoint *without the domain* and the body in plain text.
+ ... Variables can and should be used in the endpoint url and in the body JSON.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ... If this keyword was already called within this test case (e.g. before POST request), there is no need to call it again.
+ ...
+ ... Usually for PATCH requests you need to know and use the ID (UID) if the resource you need to update.
+ ... To get the ID you need forst to make a POST or GET request to get the data and then call ``Save value to a variable:`` endpoint to save the ID to a test variable to be able to use it in the PATCH request.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... At the moment Spryker does not offer this type of calls, so example is theoretical.
+ ...
+ ... ``I send a PATCH request: /some-endpoint/${someID} This is plain text body``
+ [Arguments] ${path} ${data} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${data}= Evaluate ${data}
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} PATCH On Session ${api_session} ${current_url}${path} data=${data} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE PATCH On Session ${api_session} ${current_url}${path} data=${data} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a GET request:
+ [Documentation] This keyword is used to make GET requests. It accepts the endpoint *without the domain*.
+ ... Variables can and should be used in the endpoint url.
+ ...
+ ... If the endpoint needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ... If this keyword was already called within this test case (e.g. before POST request), there is no need to call it again.
+ ...
+ ... Sometimes for GET requests you need to know and use the ID (UID) if the resource you need to view.
+ ... To get the ID you need forst to make a POST or GET request to get the data and then call ``Save value to a variable:`` endpoint to save the ID to a test variable to be able to use it in the GET request.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ...
+ ... *Example:*
+ ...
+ ... ``I send a GET request: /abstract-products/${abstract_sku}``
+ [Arguments] ${path} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} GET On Session ${api_session} ${current_url}${path} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE GET On Session ${api_session} ${current_url}${path} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+I send a DELETE request:
+ [Documentation] This keyword is used to make DELETE requests. It accepts the endpoint *without the domain*.
+ ... Variables can and should be used in the endpoint url.
+ ...
+ ... This endpoint usually needs to have any headers (e.g. token for authorisation), ``I set Headers`` keyword should be called before this keyword to set the headers beforehand.
+ ... If this keyword was already called within this test case (e.g. before POST request), there is no need to call it again.
+ ...
+ ... For DELETE requests you need to know and use the ID (UID) if the resource you need to delete.
+ ... To get the ID you need forst to make a POST or GET request to get the data and then call ``Save value to a variable:`` endpoint to save the ID to a test variable to be able to use it in the GET request.
+ ...
+ ... After this keyword is called, response body, selflink, response status and headers are recorded into the test variables which have the scope of the current test and can then be used by other keywords to get and compare data.
+ ... Body is recorded only in case there was an error, if DELETE endpoint worked without errors, reqponse body is empty and so not recorded.
+ ...
+ ... *Example:*
+ ...
+ ... For example below you will need to set headers and get address UID and customer reference recorded into a variables before you can call the DELETE request.
+ ...
+ ... ``I send a DELETE request: /customers/${customer_reference}/addresses/addressUID``
+ [Arguments] ${path} ${timeout}=${api_timeout} ${allow_redirects}=${default_allow_redirects} ${auth}=${default_auth} ${expected_status}=ANY
+ Setup_api_host_if_undefined
+ ${headers_not_empty} Run Keyword and return status Should not be empty ${headers}
+ ${response}= IF ${headers_not_empty} DELETE On Session ${api_session} ${current_url}${path} headers=${headers} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ... ELSE DELETE On Session ${api_session} ${current_url}${path} timeout=${timeout} allow_redirects=${allow_redirects} auth=${auth} expected_status=${expected_status} verify=${verify_ssl}
+ ${response_headers}= Set Variable ${response.headers}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Test Variable ${response} ${response}
+ Set Test Variable ${response_headers} ${response_headers}
+ Set Test Variable ${response_body} ${response_body}
+ Set Test Variable ${expected_self_link} ${current_url}${path}
+ RETURN ${response_body}
+
+Response reason should be:
+ [Documentation] This keyword checks that response reason saved in ``{response}`` test variable matches the reason passed as an argument.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response reason should be: Created``
+ [Arguments] ${reason}
+ Should Be Equal As Strings ${reason} ${response.reason} Expected 'reason': '${reason}' does not equal actual 'reason': '${response.reason}'
+
+Response status code should be:
+ [Documentation] This keyword checks that response status code saved in ``{response}`` test variable matches the status code passed as an argument.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response status code should be: 201``
+ [Arguments] ${status_code}
+ Should Be Equal As Strings ${response.status_code} ${status_code} Expected 'status code': '${status_code}' does not equal actual 'status code': '${response.status_code}'.
+
+Response body should contain:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the string passed as an argument.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body should contain: "localizedName": "Weight"``
+ [Arguments] ${value}
+ ${response_body}= Convert To String ${response_body}
+ ${response_body}= Replace String ${response_body} ' "
+ Should Contain ${response_body} ${value} Response body does not contain expected: '${value}'.
+
+Response body should not contain:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable does not contain the string passed as an argument.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body should not contain: "localizedName": "Weight"``
+ [Arguments] ${value}
+ ${response_body}= Convert To String ${response_body}
+ ${response_body}= Replace String ${response_body} ' "
+ Should Not Contain ${response_body} ${value} Response body contains not expected: '${value}'.
+
+Response body parameter should be:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` with the specified value ``{expected_value}``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should be: [data][0][type] abstract-product-availabilities``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Be Equal ${data} ${expected_value} Response data in: '${json_path}', does not equal expected: '${expected_value}', actual is: '${data}'.
+
+Response body case-insensitive parameter should be:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` with the specified case-insensitive value ``{expected_value}``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body case-insensitive parameter should be: [data][0][type] Abstract-Product-Availabilities``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ ${data}= Convert To Lower Case ${data}
+ ${expected_value}= Convert To Lower Case ${expected_value}
+ Should Be Equal ${data} ${expected_value} Response data in: '${json_path}', does not equal expected: '${expected_value}', actual is: '${data}'.
+
+Perform arithmetical calculation with two arguments:
+ [Documentation] This keyword calculates ``{expected_value1}``, ``{expected_value2}`` and saves in ``{variable_name}`` variable.
+ ...
+ ... First you need to set variable name. You can use also existing variable name, in this case variable should be overwritten.
+ ... Set integer values for ${expected_value1} and ${expected_value2}, add supported math symbol {'+', '-', '*', '/'} for ``{math_symbol}``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${discount.product_3.with_10%_discount}``
+ [Arguments] ${variable_name} ${expected_value1} ${math_symbol} ${expected_value2}
+ IF '${math_symbol}' == '+'
+ ${result} Evaluate ${expected_value1} + ${expected_value2}
+ ELSE IF '${math_symbol}' == '-'
+ ${result} Evaluate ${expected_value1} - ${expected_value2}
+ ELSE IF '${math_symbol}' == '*'
+ ${result} Evaluate ${expected_value1} * ${expected_value2}
+ ELSE IF '${math_symbol}' == '/'
+ ${result} Evaluate ${expected_value1} / ${expected_value2}
+ ELSE
+ ${result} Set Variable None
+ END
+ ${result}= Convert To String ${result}
+ Set Test Variable ${${variable_name}} ${result}
+ RETURN ${variable_name}
+
+Response body parameter should be in:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` with the value that matches one of the parameters ``{expected_value1}``, ``{expected_value2}``.
+ ...
+ ... The minimal number of arguments are 2, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should be in: [data][attributes][allowInput] true false``
+ [Arguments] ${json_path} ${expected_value1} ${expected_value2} ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value ${expected_value5}=robotframework-dummy-value ${expected_value6}=robotframework-dummy-value ${expected_value7}=robotframework-dummy-value ${expected_value8}=robotframework-dummy-value ${expected_value9}=robotframework-dummy-value
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ TRY
+ Should Contain Any ${data} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ${expected_value5} ${expected_value6} ${expected_value7} ${expected_value8} ${expected_value9} ignore_case=True
+ EXCEPT
+ Fail Response data in: '${json_path}', does not contains any: '${expected_value1}', '${expected_value2}', '${expected_value3}', '${expected_value4}', '${expected_value5}', '${expected_value6}', '${expected_value7}', '${expected_value8}', '${expected_value9}', in '${data}'.
+ END
+
+Response body parameter with rounding should be:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` that was rounded and can differ from the expected value by 1 more cent or 1 less cent.
+ ... It can be used if you need to check value with rounding for prices etg.
+ ...
+ ... Range is calculated as
+ ...
+ ... Minimal range: ``{expected_value}`` - ``1``
+ ... Maximum range: ``{expected_value}`` + ``1``
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter with rounding should be: [data][attributes][discounts][0][amount] ${discount.product_3.with_10%_discount}``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ ${range_value_min}= Evaluate ${expected_value} - 1
+ ${range_value_max}= Evaluate ${expected_value} + 1
+ IF ${data} >= ${range_value_min} and ${data} <= ${range_value_max}
+ ${result} Set Variable True
+ ELSE
+ ${result} Set Variable False
+ END
+ Should Be Equal ${result} True Actual ${data} is not in expected Range [${range_value_min}; ${range_value_max}], json_path: '${json_path}'
+
+Response body parameter should be NOT in:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` with the value that matches one of the parameters ``{expected_value1}``, ``{expected_value2}``.
+ ...
+ ... The minimal number of arguments is 1, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should be NOT in: [data][attributes][allowInput] None``
+ [Arguments] ${json_path} ${expected_value1} ${expected_value2}=robotframework-dummy-value ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ TRY
+ Should NOT Contain Any ${data} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Response data in: '${json_path}', should not contain any: ${expected_value1}, ${expected_value2}, ${expected_value3}, ${expected_value4} in '${data}'.
+ END
+
+Response body parameter should NOT be:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{json_path}`` has a value that is DIFFERENT from the value passed as an argument ``{expected_value}``.
+ ...
+ ... This keyword can be conveniently used when you need to make sure the parameter is not empty. To check for ``null`` value in robot Framework use ``None`` keyword as shown in the example below.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should NOT be: data.id None``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Not Be Empty ${data} '${data}' in '${json_path}' is empty but should not be.
+ Should Not Be Equal ${data} ${expected_value} '${data}' in '${json_path}' should be equal to '${expected_value}'.
+
+Response body parameter should have datatype:
+ [Documentation] This keyword checks that the response saved in ``{response_body}`` test variable contains the specified parameter ``{parameter}`` and that parameter has the specified data type ``{expected_data_type}``.
+ ...
+ ... Some types that can be used are: ``int``, ``str``, ``list``. It uses a custom keyword ``Evaluate datatype of a variable:`` to evaluate the datatype.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should have datatype: [data][0][attributes][name] str``
+ ... ``Response body parameter should have datatype: [data][0][attributes][sort][sortParamNames] list``
+ [Arguments] ${parameter} ${expected_data_type}
+ @{parameter}= Get Value From Json ${response_body} ${parameter}
+ ${actual_data_type}= Evaluate datatype of a variable: @{parameter}
+ Should Be Equal ${actual_data_type} ${expected_data_type} Parameter: '${parameter}' should be '${expected_data_type}' but got: '${actual_data_type}'.
+
+Evaluate datatype of a variable:
+ [Documentation] This is a technical keyword that is used in ``Response body parameter should have datatype:`` and is used to evaluate the actual data type of a variable.
+ ...
+ ... Example of assertions:
+ ...
+ ... ``{is int}= Evaluate isinstance($variable, int) `` will be True
+ ...
+ ... ``{is string}= Evaluate isinstance($variable, str) `` will be False
+ [Arguments] ${variable}
+ ${data_type}= Evaluate type($variable).__name__
+ RETURN ${data_type}
+
+Response header parameter should be:
+ [Documentation] This keyword checks that the response header saved previiously in ``{response_headers}`` test variable has the expected header with name ``{header_parameter}`` and this header has value ``{header_value}``
+ ...
+ ... *Example:*
+ ...
+ ... ``Response header parameter should be: Content-Type ${default_header_content_type}``
+ [Arguments] ${header_parameter} ${header_value}
+ ${actual_header_value}= Get From Dictionary ${response_headers} ${header_parameter}
+ Should Be Equal ${actual_header_value} ${header_value} Header parameter: '${header_parameter}' should have value: '${header_value}' but got: '${actual_header_value}'.
+
+Response header parameter should contain:
+ [Documentation] This keyword checks that the response header saved previiously in ``{response_headers}`` test variable has the expected header with name ``{header_parameter}`` and this header contains substring ``{header_value}``
+ ...
+ ... *Example:*
+ ...
+ ... ``Response header parameter should be: Content-Type ${default_header_content_type}``
+ [Arguments] ${header_parameter} ${header_value}
+ ${actual_header_value}= Get From Dictionary ${response_headers} ${header_parameter}
+ Should Contain ${actual_header_value} ${header_value} Header parameter: '${header_parameter}' should contain value: '${header_value}' but got: '${actual_header_value}'.
+
+Response body has correct self link
+ [Documentation] This keyword checks that the actual selflink retrieved from the test variable ``{response_body}`` matches the self link recorded into the ``{expected_self_link}`` test variable on endpoint call.
+ ...
+ ... This keyword does not accept any arguments. Expected self link on the endpoint call as assembled from the domain and the endpoint passed to the request.
+ ...
+ ... *NOTE:* this keyword checks the first link that is OUTSUDE of the ``data[]`` array in the response
+ ${actual_self_link}= Get Value From Json ${response_body} $.links.self #Exampleof path: $..address.streetAddress
+ ${actual_self_link}= Convert To String ${actual_self_link}
+ ${actual_self_link}= Replace String ${actual_self_link} [ ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ] ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ' ${EMPTY}
+ Should Be Equal ${actual_self_link} ${expected_self_link} Expected self link: '${expected_self_link}' does not match actual link: '${actual_self_link}'.
+
+Response body has correct self link internal
+ [Documentation] This keyword checks that the actual selflink retrieved from the test variable ``{response_body}`` matches the self link recorded into the ``{expected_self_link}`` test variable on endpoint call.
+ ...
+ ... This keyword does not accept any arguments. Expected self link on the endpoint call as assembled from the domain and the endpoint passed to the request.
+ ...
+ ... *NOTE:* this keyword checks the first link that is INSIDE of the ``data[]`` array in the response.
+ ${actual_self_link}= Get Value From Json ${response_body} [data][links][self] #Exampleof path: $..address.streetAddress
+ ${actual_self_link}= Convert To String ${actual_self_link}
+ ${actual_self_link}= Replace String ${actual_self_link} [ ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ] ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ' ${EMPTY}
+ Should Be Equal ${actual_self_link} ${expected_self_link} Expected internal self link: '${expected_self_link}' does not match the actual link: '${actual_self_link}'.
+
+Response body has correct self link for created entity:
+ [Documentation] This keyword checks that the actual selflink retrieved from the test variable ``{response_body}`` plus the UID of the entity that was created and matches the self link recorded into the ``{expected_self_link}`` test variable on endpoint call.
+ ...
+ ... This keyword requires one argument which is the ending of the URL usually containing the UID of the created resource. Expected self link on the endpoint call as assembled from the domain, the endpoint passed to the request and the end of the URTL passed as the argument.
+ ...
+ ... *NOTE:* this keyword checks the first link that is INSIDE of the ``data[]`` array in the response.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body has correct self link for created entity: ${address_uid_1}``
+ ...
+ ... ``Response body has correct self link for created entity: 687b806f-2fab-555f-90ae-e32d96b6aa71``
+ ...
+ ... In the case above the self link for create cart would be ``glue.domain/carts/687b806f-2fab-555f-90ae-e32d96b6aa71``, ``{expected_self_link}`` would be ``glue.domain/carts/`` and the UID will come from the argument.
+ [Arguments] ${url} #the ending of the url, usually the ID
+ ${actual_self_link}= Get Value From Json ${response_body} [data][links][self] #Exampleof path: $..address.streetAddress
+ ${actual_self_link}= Convert To String ${actual_self_link}
+ ${actual_self_link}= Replace String ${actual_self_link} [ ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ] ${EMPTY}
+ ${actual_self_link}= Replace String ${actual_self_link} ' ${EMPTY}
+ Should Be Equal ${actual_self_link} ${expected_self_link}/${url} Expected self link for created entity: '${expected_self_link}/${url}' does not match actual self link for created entity: '${actual_self_link}'.
+
+Response body parameter should not be EMPTY:
+ [Documentation] This keyword checks that the body parameter sent in ``{json_path}`` argument is not empty. If the parameter value is other that ``null`` the keyword will fail.
+ ...
+ ... This keyword checks both that the parameter does not have null value or that it does not have an empty string value and makes sure that the pagameter actually exists.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should not be EMPTY: [data][attributes][description]``
+ [Arguments] ${json_path}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Not Be Empty ${data} '${json_path}' property value '${data}' is empty but shoud not be
+ Should Not Be Equal ${data} None '${json_path}' property value is '${data}' which is null, but it shoud be a non-null.
+
+Response body parameter should be greater than:
+ [Documentation] This keyword checks that the body parameter sent in ``{json_path}`` argument is greater than a specific integer value ``{expected_value}``.
+ ... It can be used to check that the number of items in stock is more than the minimum, that the number of returned products or cms pages in search is more than the minimum.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should be greater than: [data][0][attributes][price] 100``
+ ...
+ ... ``Response body parameter should be greater than: data[0].attributes.dateSchedule[0].date ${today}``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ ${result}= Evaluate float('${data}') > float('${expected_value}')
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual '${data}' is not greater than expected '${expected_value}' in '${json_path}'.
+
+Response body parameter should be less than:
+ [Documentation] This keyword checks that the body parameter sent in ``{json_path}`` argument is less than a specific integer value ``{expected_value}``.
+ ... It can be used to check that the default price of the product is less than the original price, that the date of the order is before the certain date.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should be less than: [data][0][attributes][price] 100``
+ ...
+ ... ``Response body parameter should be less than: data[0].attributes.dateSchedule[0].date 2019-01-01``
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ ${result}= Evaluate '${data}' < '${expected_value}'
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual '${data}' is not less than expected '${expected_value}' in '${json_path}'.
+
+Response should contain the array of a certain size:
+ [Documentation] This keyword checks that the body array sent in ``{json_path}`` argument contains the specific number of items ``{expected_size}``. The expected size should be an integer value.
+ ... It can be used to check how many products, addresses, etc. were returned, if you know the exact number of elements that should be returned.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1``
+ [Arguments] ${json_path} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To String ${list_length}
+ Should Be Equal ${list_length} ${expected_size} actual size '${list_length}' doesn't equal expected '${expected_size}' in '${json_path}'.
+
+Response should contain the array of size in:
+ [Documentation] This keyword verifies that the array at the given JSON path has a length equal to one of the expected sizes provided.
+ ... It accepts one or more expected sizes as optional arguments.
+ [Arguments] ${json_path} @{expected_sizes}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${actual_length}= Get Length @{data}
+ ${actual_length}= Convert To String ${actual_length}
+ Should Contain ${expected_sizes} ${actual_length} msg=Actual size '${actual_length}' does not match any of the expected sizes '${expected_sizes}' in '${json_path}'.
+
+Response should contain the array larger than a certain size:
+ [Documentation] This keyword checks that the body array sent in ``{json_path}`` argument contains the number of items that is more than ``{expected_size}``.
+ ... The expected size should be an integer value that is less than you expect elements. So if you expect an array to have at least 2 elements, the ``{expected_size}`` should be 1.
+ ...
+ ... It can be used to check how many elements were returned, if you know the exact number of elements that should be returned, but know there should be at least 1 for example.
+ ...
+ ... *Example:*
+ ...
+ ... `` Response should contain the array larger than a certain size: [data][relationships][category-nodes][data] 1``
+ [Arguments] ${json_path} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ ${result}= Evaluate ${list_length} > ${expected_size}
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual array length is '${list_length}' and it is not greater than expected '${expected_size}' in '${json_path}'.
+
+Response should contain the array larger or equal than a certain size:
+ [Documentation] This keyword checks that the body array sent in ``{json_path}`` argument contains the number of items that is more than ``{expected_size}`` or equals.
+ ... *Example:*
+ ...
+ ... `` Response should contain the array larger or equal than a certain size: Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}+1``
+ [Arguments] ${json_path} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ ${expected_size}= Evaluate ${expected_size}
+ ${expected_size}= Convert To Integer ${expected_size}
+ ${result}= Evaluate ${list_length} >= ${expected_size}
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual array length is '${list_length}' and it is not greater (or equal) than expected '${expected_size}' in '${json_path}'.
+
+Response should contain the array less or equal than a certain size:
+ [Documentation] This keyword checks that the body array sent in ``{json_path}`` argument contains the number of items that is less than ``{expected_size}`` or equals.
+ ... *Example:*
+ ...
+ ... `` Response should contain the array less or equal than a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}``
+ [Arguments] ${json_path} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ ${expected_size}= Evaluate ${expected_size}
+ ${expected_size}= Convert To Integer ${expected_size}
+ ${result}= Evaluate ${list_length} <= ${expected_size}
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual array length is '${list_length}' and it is not less (or equal) than expected '${expected_size}' in '${json_path}'.
+
+Each array element of the array in response should contain a nested array larger than a certain size:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the `` ${nested_array}` with certain size greater than ``{expected_size}``.
+ ...
+ ... If at least one array element has ``{nested_array} `` less than ``{expected_size}``, the keyword will fail.
+
+ ... *Example:*
+ ...
+ ... `` Each array element of the array in response should contain a nested array larger than a certain size: [data] [attributes][stores] 0``
+ [Arguments] ${json_path} ${nested_array} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Get From List @{data} ${index}
+ @{data}= Get Value From Json ${list_length} ${nested_array}
+ ${nested_array_list_length}= Get Length @{data}
+ ${result}= Evaluate ${nested_array_list_length} > ${expected_size}
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual nested array length is '${nested_array_list_length}' not greater than expected '${expected_size}'.
+ END
+
+Response should contain the array smaller than a certain size:
+ [Documentation] This keyword checks that the body array sent in ``{json_path}`` argument contains the number of items that is fewer than ``{expected_size}``.
+ ... The expected size should be an integer value that is less than you expect elements. So if you expect an array to have 0 or 1 elements, the ``{expected_size}`` should be 2.
+ ...
+ ... It can be used to check how many elements were returned, if you know the exact number of elements that should be returned, but know there should be fewer, than the default value for example.
+ ... It is useful when you check search and know how many values are there if there is no filtering, but you also know that with filtering, there should be fewer values than without it.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][1] 5``
+ [Arguments] ${json_path} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ ${result}= Evaluate ${list_length} < ${expected_size}
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual array length is '${list_length}' and it is not smaller than expected '${expected_size}' in '${json_path}'.
+
+Each array element of array in response should contain property:
+ [Documentation] This keyword checks whether the array ``{json_path}`` that is present in the ``{response_body}`` test variable contains a property with ``{expected_property}`` name in every of it's array elements.
+ ...
+ ... It does not take into account the property value, just checks it is there for every element. If some of the elements have this property and others do not, the keyword will fail.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity``
+ ...
+ ... The example above checks if ALL prices returned in volumePrices array have quantity property, while quantity value can be any and even null.
+ [Arguments] ${json_path} ${expected_property}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ List Should Contain Value ${list_element} ${expected_property} msg=Array element '${list_element}' of array '${json_path}' does not contain property: '${expected_property}'.
+ END
+
+Each array element of array in response should contain value:
+ [Documentation] This keyword checks whether the array ``{json_path}`` that is present in the ``{response_body}`` test variable contains a value ``{expected_value}`` in every of it's array elements.
+ ...
+ ... It does not take into account the property name, just checks if the value is there for every element. If some of the array elements have this value and others do not, the keyword will fail.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.code}``
+ ...
+ ... The example above checks if ALL prices returned in volumePrices array have currency code, regardless of which property has this value.
+ [Arguments] ${json_path} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${sub_list_element}= Create List ${list_element}
+ ${sub_list_element}= Convert To String ${sub_list_element}
+ Should Contain : ${sub_list_element} ${expected_value} msg=Array element:'${sub_list_element}' of array:'${json_path}' does not contain:'${expected_value}'.
+ END
+
+Each array element of array in response should contain a nested array of a certain size:
+ [Documentation] This keyword checks whether the array ``{parent_array}`` that is present in the ``{response_body}`` test variable contains an array ``{nested_array}`` in every of it's array elements and for every its occurrence that nested array has sixe ``{array_expected_size}``.
+ ...
+ ... If the nested arrays are of different sizes, this keyword will fail.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain a nested array of a certain size: [data] [prices] 2``
+
+ [Arguments] ${parent_array} ${nested_array} ${array_expected_size}
+ @{data}= Get Value From Json ${response_body} ${parent_array}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ @{list_element2}= Get Value From Json ${list_element} ${nested_array}
+ ${list_length2}= Get Length @{list_element2}
+ ${list_length2}= Convert To String ${list_length2}
+ Should Be Equal ${list_length2} ${array_expected_size} Actual nested array size:'${list_length2}' in '${nested_array}' does not match '${array_expected_size}'.
+ END
+
+Each array element of array in response should contain property with value:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_property}`` with the specified value ``{expected_value}``.
+ ...
+ ... If at least one array element has this property with another value, the keyword will fail.
+ ...
+ ... *NOTE*: ``{expected_property}`` is a first level property in an array like this ``"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...] e.g. ``attributes``.
+ ... While second level property is `attributes.sku`` and it won't be identified with this keyword.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain property with value: [errors] status 422``
+ ...
+ ... ``Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices []``
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ Dictionary Should Contain Item ${list_element} ${expected_property} ${expected_value} msg='${json_path}' does not contain property: '${expected_property}' with value: '${expected_value}'.
+ END
+
+Each array element of array in response should contain property with value in:
+ [Documentation] This keyword checks that each array element contains the specified parameter ``{expected_property}`` with the value that matches one of the parameters ``{expected_value1}``, ``{expected_value2}``, etc..
+ ...
+ ... The minimal number of arguments are 2, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain property with value in: [data] [attributes][allowInput] True False``
+ [Arguments] ${json_path} ${expected_property} ${expected_value1} ${expected_value2} ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Contain Any ${list_element} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Array element: '${expected_property}' of array: '${json_path}' does not contain any: ${expected_value1}, ${expected_value2}, ${expected_value3}, ${expected_value4}
+ END
+ END
+
+Each array in response should contain property with NOT EMPTY value:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_property}`` with NOT EMPTY value.
+ ...
+ ... If at least one array element has this property with EMPTY value, the keyword will fail.
+
+ ... *Example:*
+ ...
+ ... ``Each array element in response should contain property with NOT EMPTY value: [data] [attributes][name]``
+
+ [Arguments] ${json_path} ${expected_property}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ Should Not Be Empty ${list_element} '${expected_property}' property value in json path '${json_path}' is empty but shoud Not Be EMPTY
+ END
+
+Each array in response should contain property with value NOT in:
+ [Documentation] This keyword checks that each array element contains the specified parameter ``{expected_property}`` with the value that does not match any of the parameters ``{expected_value1}``, ``{expected_value2}``, etc..
+ ...
+ ... The minimal number of arguments is 1, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element in response should contain property with value NOT in: [data] [attributes][isSuper] None``
+ [Arguments] ${json_path} ${expected_property} ${expected_value1} ${expected_value2}=robotframework-dummy-value ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Not Contain Any ${list_element} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Element: '${expected_property}' of array: '${json_path}' contain any but SHOULD NOT: ${expected_value1}, ${expected_value2}, ${expected_value3}, ${expected_value4}
+ END
+ END
+
+Each array element of array in response should contain property with value NOT in:
+ [Documentation] This keyword checks that each array element of array contains the specified parameter ``{expected_property}`` with the value that does not match any of the parameters ``{expected_value1}``, ``{expected_value2}``, etc..
+ ...
+ ... The minimal number of arguments is 1, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain property with value NOT in: [data] [attributes][isSuper] None``
+ [Arguments] ${json_path} ${expected_property} ${expected_value1} ${expected_value2}=robotframework-dummy-value ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Not Contain Any ${list_element} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Array element: '${expected_property}' of array: '${json_path}' contain any but SHOULD NOT: ${expected_value1}, ${expected_value2}, ${expected_value3}, ${expected_value4}
+ END
+ END
+
+Each array element of array in response should NOT be empty:
+ [Documentation] This keyword checks that each array element of array contains the specified parameter ``{expected_property}`` with the value that does not empty.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should NOT be empty: [data] id``
+ [Arguments] ${json_path} ${expected_property}
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Not Be Empty ${list_element}
+ EXCEPT
+ Fail Array element: '${expected_property}' of array: '${json_path}' is empty but SHOULD NOT
+ END
+ END
+
+Each array element of nested array should contain property with value in:
+ [Documentation] This keyword checks that each array element of ``{nested_array} that is inside the parent array ``{json_path}`` contains the specified parameter ``{expected_property}`` with the value that matches any of the parameters ``{expected_value1}``, ``{expected_value2}``, etc..
+ ...
+ ... The minimal number of arguments is 1, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] translation en_US de_DE``
+ [Arguments] ${json_path} ${nested_array} ${expected_property} ${expected_value1} ${expected_value2} ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length1}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index1} IN RANGE 0 ${list_length1}
+ ${list_element}= Get From List @{data} ${index1}
+ @{list_element2}= Get Value From Json ${list_element} ${nested_array}
+ ${list_length2}= Get Length @{list_element2}
+ FOR ${index2} IN RANGE 0 ${list_length2}
+ ${list_element}= Get From List @{list_element2} ${index2}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Contain Any ${list_element} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Nested array:'${nested_array}' of array:'${json_path}' does NOT contain property:'${expected_property}' with value in: ${expected_value1}, ${expected_value2}, ${expected_value3}, ${expected_value4}
+ END
+ END
+ END
+
+Each array element of nested array should contain property with value NOT in:
+ [Documentation] This keyword checks that each array element of ``{nested_array} that is inside the parent array ``{json_path}`` contains the specified parameter ``{expected_property}`` with the value that does not match any of the parameters ``{expected_value1}``, ``{expected_value2}``, etc..
+ ...
+ ... The minimal number of arguments is 1, maximum is 4
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of nested array should contain property with value NOT in: [data] [attributes][localizedKeys] translation None``
+ [Arguments] ${json_path} ${nested_array} ${expected_property} ${expected_value1} ${expected_value2}=robotframework-dummy-value ${expected_value3}=robotframework-dummy-value ${expected_value4}=robotframework-dummy-value
+
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length1}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index1} IN RANGE 0 ${list_length1}
+ ${list_element}= Get From List @{data} ${index1}
+ @{list_element2}= Get Value From Json ${list_element} ${nested_array}
+ ${list_length2}= Get Length @{list_element2}
+ FOR ${index2} IN RANGE 0 ${list_length2}
+ ${list_element}= Get From List @{list_element2} ${index2}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ TRY
+ Should Not Contain Any ${list_element} ${expected_value1} ${expected_value2} ${expected_value3} ${expected_value4} ignore_case=True
+ EXCEPT
+ Fail Nested array:'${nested_array}' of array:'${json_path}' contain property:'${expected_property}' with value in: '${expected_value1}', '${expected_value2}', '${expected_value3}', '${expected_value4}', BUT SHOULD NOT!
+ END
+ END
+ END
+
+Each array element of array in response should contain nested property with value:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` with the specified value ``{expected_value}``.
+ ...
+ ... If at least one array element has this property with another value, the keyword will fail.
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ... 4. This keyword supports any level of nesting.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain nested property with value: [data] [attributes][sku] "M1234"``
+ ...
+ ... ``Each array element of array in response should contain nested property with value: [data] attributes.sku "M1234"``
+ ...
+ ... ``Each array element of array in response should contain nested property with value: [data] [relationships][concrete-products][data][0][type] concrete-products``
+ [Arguments] ${json_path} ${expected_nested_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ Should Be Equal ${list_element} ${expected_value}
+ END
+
+Each array element of array in response should contain nested property in range:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` that's in the range between ``{lower_value}`` and ``{higher_value}``
+ ...
+ ... If at least one array element has this property not in this range, the keyword will fail.
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain nested property in range: [data] [attributes][sku] 0 10``
+ ...
+ ... ``Each array element of array in response should contain nested property in range: [data] attributes.sku 20 100``
+ ...
+ ... ``Each array element of array in response should contain nested property in range: [data] [relationships][concrete-products][data][0][price] 10 500``
+ [Arguments] ${json_path} ${expected_nested_property} ${lower_value} ${higher_value}
+ IF ${lower_value} == ${higher_value} Fail Your higher and lower values cannot be the same.
+ IF ${lower_value} > ${higher_value} Fail Your lower value cannot be greater than the lower value.
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ IF ${list_element} < ${lower_value} Fail Value ${list_element} is less than lower value ${lower_value}.
+ IF ${list_element} > ${higher_value} Fail Value ${list_element} is greater than higher value ${higher_value}.
+ END
+
+Each array element of array in response should be greater than:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` that's greater than ``{expected_value}``
+ ...
+ ... If at least one array element has this property not greater than ``{expected_value}``, the keyword will fail.
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should be greater than: [data] [attributes][price] 1000``
+ ...
+ ... ``Each array element of array in response should be greater than: [data] attributes.price 2000``
+ ...
+ ... ``Each array element of array in response should be greater than: [data] [relationships][concrete-products][data][0][price] 5000``
+ [Arguments] ${json_path} ${expected_nested_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ ${result}= Evaluate '${list_element}' > '${expected_value}'
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual ${list_element} is not greater than expected ${expected_value}
+ END
+
+Each array element of array in response should be less than:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` that's less than ``{expected_value}``
+ ...
+ ... If at least one array element has this property not less than ``{expected_value}``, the keyword will fail.
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should be less than: [data] [attributes][price] 1000``
+ ...
+ ... ``Each array element of array in response should be less than: [data] attributes.price 2000``
+ ...
+ ... ``Each array element of array in response should be less than: [data] [relationships][concrete-products][data][0][price] 5000``
+ [Arguments] ${json_path} ${expected_nested_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ ${result}= Evaluate '${list_element}' < '${expected_value}'
+ ${result}= Convert To String ${result}
+ Should Be Equal ${result} True Actual ${list_element} is not less than expected ${expected_value}
+ END
+
+Each array element of array in response should contain nested property with datatype:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` with the value of the specified data type ``{expected_type}``.
+ ...
+ ... If at least one array element has this property with another value, the keyword will fail.
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ... 4. This keyword supports any level of nesting.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain nested property with datatype: [data] [attributes][sku] str``
+ ...
+ ... ``Each array element of array in response should contain nested property with datatype: [data] attributes.price int``
+ [Arguments] ${json_path} ${expected_nested_property} ${expected_type}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ @{list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${actual_data_type}= Evaluate datatype of a variable: @{list_element}
+ Should Be Equal ${actual_data_type} ${expected_type}
+ END
+
+Each array element of array in response should contain nested property with datatype in:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{expected_nested_property}`` with the value of one of the specified data types ``{expected_type1}``, ``{expected_type1}``, etc..
+ ...
+ ... This keyword requires 2 parameters and may optionally use up to 4 datatypes
+ ...
+ ... *NOTES*:
+ ...
+ ... 1. ``{expected_nested_property}`` is a second level property. In an array like this
+ ...
+ ... ``{"data":[{"type": "some-type", "attributes": {"name": "some name", "sku": "1234"}},...]}``
+ ...
+ ... it will be ``attributes.sku``.
+ ...
+ ... 2. The first level property in the above array is just ``attributes``, but it cannot be checked by this keyword.
+ ...
+ ... 3. Syntax for the second level property is ``[firstlevel][secondlevel]`` or ``firstlevel.secondlevel``.
+ ...
+ ... 4. This keyword supports any level of nesting.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain nested property with datatype in: [data] attributes.price int float``
+ [Arguments] ${json_path} ${expected_nested_property} ${expected_type1} ${expected_type2} ${expected_type3}=test ${expected_type4}=test
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ @{list_element}= Get Value From Json ${list_element} $.${expected_nested_property}
+ ${actual_data_type}= Evaluate datatype of a variable: @{list_element}
+ Should Contain Any ${actual_data_type} ${expected_type1} ${expected_type2} ${expected_type3} ${expected_type4}
+ END
+
+Each array element of array in response should contain nested property:
+ [Documentation] This keyword checks that each element in the array specified as ``{json_path}`` contains the specified property ``{level1_property}``, that is not an array and contains a certain second level property ``{level2_property}``,.
+ ...
+ ... *Example:*
+ ...
+ ... ``Each array element of array in response should contain nested property: [data] [attributes] sku``
+ ...
+ ... The example above checks if inside [data] array there is property attributes and inside that there is sku property
+ [Arguments] ${json_path} ${level1_property} ${level2_property}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${list_element}= Get Value From Json ${list_element} ${level1_property}
+ ${list_element}= Convert To String ${list_element}
+ Should Contain ${list_element} ${level2_property}
+ END
+
+
+Response should return error message:
+ [Documentation] This keyword checks if the ``{response_body}`` test variable that contains the response of the previous request contains the specific ``{error_message}``.
+ ...
+ ... Call only for negative tests where you expect an error. NOTE: it checks only the first error, if there are more than one, better use this keyword: ``Array in response should contain property with value``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should return error message: Can`t find abstract product image sets.``
+ [Arguments] ${error_message}
+ FOR ${tag} IN @{Test Tags}
+ IF '${tag}'=='bapi' or '${tag}'=='sapi'
+ ${data}= Get Value From Json ${response_body} [errors][0][message]
+ END
+ IF '${tag}'=='glue'
+ ${data}= Get Value From Json ${response_body} [errors][0][detail]
+ END
+ END
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Be Equal ${data} ${error_message} Actual '${data}' error reason doens't match expected '${error_message}'
+
+Response should return error code:
+ [Documentation] This keyword checks if the ``{response_body}`` test variable that contains the response of the previous request contains the specific ``{error_code}``.
+ ...
+ ... Call only for negative tests where you expect an error. NOTE: it checks only the first error code in the array, if there are more than one error, better use this keyword: ``Array in response should contain property with value``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should return error code: 204``
+ [Arguments] ${error_code}
+ ${error_code}= Convert To String ${error_code}
+ ${data}= Get Value From Json ${response_body} [errors][0][code]
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Be Equal ${data} ${error_code} Actual '${data}' response error code doesn't match expected '${error_code}'
+
+Response should contain certain number of values:
+ [Documentation] This keyword checks if a certain response parameter ``{json_path} `` in the ``{response_body}`` test variable has the specified number ``{expected_count}`` of the specified values ``{expected_value}`` in it.
+ ...
+ ... It can check that response contains 5 categories or 4 cms pages.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should contain certain number of values: [data][attributes][nodes] cms_page 4``
+ [Arguments] ${json_path} ${expected_value} ${expected_count}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ # ${log_list}= Log List @{data}
+ ${list_as_string}= Convert To String @{data}
+ ${count}= Get Count : ${list_as_string} ${expected_value}
+ ${count}= Convert To String ${count}
+ Should Be Equal ${count} ${expected_count} Actual count '${count}' of '${expected_value}' in '${json_path}' does not match '${expected_count}'
+
+Response include should contain certain entity type:
+ [Documentation] This keyword checks that a certain entity with type ``{expected_value}`` is included into the ``[included]`` section of the ``{response_body}`` test variable.
+ ... It accepts the type of the included entity (usually can be found in [included][index][type]) and checks if such entity exists in the response at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response include should contain certain entity type: concrete-products``
+ [Arguments] ${expected_value} #this should be the 'type' of the included item, e.g. abstract-product-prices
+ @{include}= Get Value From Json ${response_body} [included]
+ ${list_length}= Get Length @{include}
+ # ${log_list}= Log List @{include}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${include_element}= Get From List @{include} ${index}
+ ${type}= Get Value From Json ${include_element} [type]
+ ${type}= Convert To String ${type}
+ ${type}= Replace String ${type} ' ${EMPTY}
+ ${type}= Replace String ${type} [ ${EMPTY}
+ ${type}= Replace String ${type} ] ${EMPTY}
+ ${result}= Evaluate '${type}' == '${expected_value}'
+ IF ${result} Exit For Loop
+ END
+ Should Be Equal As Strings ${result} True Include section '${expected_value}' was not found
+
+Response include element has self link:
+ [Documentation] This keyword checks that the ``[included]`` section of the response contains a self link in the included element with ``{expected_value}`` type.
+ ...
+ ... This keyword does accepts type of the included element as the parameter. If there is not include with this type or the include with this type does not have/has wrong selflink, the keyword will fail.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response include element has self link: concrete-products``
+ [Arguments] ${expected_value} #this should be the 'type' of the included item, e.g. abstract-product-prices
+ @{include}= Get Value From Json ${response_body} [included]
+ ${list_length}= Get Length @{include}
+ # ${log_list}= Log List @{include}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${include_element}= Get From List @{include} ${index}
+ ${type}= Get Value From Json ${include_element} [type]
+ ${type}= Convert To String ${type}
+ ${type}= Replace String ${type} ' ${EMPTY}
+ ${type}= Replace String ${type} [ ${EMPTY}
+ ${type}= Replace String ${type} ] ${EMPTY}
+ ${result}= Evaluate '${type}' == '${expected_value}'
+ ${link_found}= IF ${result} Get Value From Json ${include_element} [links][self]
+ IF ${link_found} Should Not Be Equal ${link_found} None ${link_found} is empty for ${expected_value} include section
+ IF ${result} Exit For Loop
+ END
+ Should Be Equal As Strings ${result} True Include section '${expected_value}' was not found
+
+Save value to a variable:
+ [Documentation] This keyword saves any value located in a response parameter ``{json_path}`` to a test variable called ``{name}``.
+ ...
+ ... It can be used to save a value returned by any request into a custom test variable.
+ ... This variable, once created, can be used during the cpecific test where this keyword is used and can be re-used by the keywords that follow this keyword in the test.
+ ... It will not be visible to other tests.
+ ...
+ ... *Examples:*
+ ...
+ ... ``Save value to a variable: [data][id] cart_uid``
+ ...
+ ... The example above should be called after POST request for cart creation. It gets cart ID from the ``{response_body}`` test vatialbe and saves it into ``{cart_uid}`` test variable whcih can then be used in other requests, e.g. in a checkout request.
+ [Arguments] ${json_path} ${name}
+ ${var_value}= Get Value From Json ${response_body} ${json_path}
+ ${var_value}= Convert To String ${var_value}
+ ${var_value}= Replace String ${var_value} ' ${EMPTY}
+ ${var_value}= Replace String ${var_value} [ ${EMPTY}
+ ${var_value}= Replace String ${var_value} ] ${EMPTY}
+ Set Test Variable ${${name}} ${var_value}
+ RETURN ${name}
+
+Save Header value to a variable:
+ [Documentation] This keyword saves any value located in a response Header parameter ``{header_parameter}`` to a test variable called ``{name}``.
+ ...
+ ... It can be used to save a value returned by any request into a custom test variable.
+ ... This variable, once created, can be used during the cpecific test where this keyword is used and can be re-used by the keywords that follow this keyword in the test.
+ ... It will not be visible to other tests.
+ ...
+ ... *Examples:*
+ ...
+ ... ``Save Header value to a variable: ETag header_tag``
+ ...
+ ... The example above should be called after POST request for cart creation. It gets ETag from the ``{response_headers}`` test vatialbe and saves it into ``{header_tag}`` test variable which can then be used in other requests, e.g. in a PATCH request.
+ [Arguments] ${header_parameter} ${name}
+ ${actual_header_value}= Get From Dictionary ${response_headers} ${header_parameter}
+ Set Test Variable ${${name}} ${actual_header_value}
+ RETURN ${name}
+
+Response body parameter should contain:
+ [Documentation] This keyword checks that response parameter with name ``{json_path}`` contains the specified substing ``{expected_value}``.
+ ... It can check that a long value has the required substing without needing to know the whole value. It is a partial patch check.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should contain: [data][attributes][superAttributes] ${abstract_sku}``
+ ...
+ ... The example above checks that ``superAttributes`` parameter contains the sku of the concrete product.
+ ... In fact this is abstract product request and this array returns the list of concrete products that are variants of this abstract.
+ ... Since in Spryker often concrete SKU includes abstract sku, this checks that the list contains abstract sku.
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Contain ${data} ${expected_value} Body parameter:'${json_path}' does not contain '${expected_value}'
+
+Response body parameter should start with:
+ [Documentation] This keyword checks that response parameter with name ``{json_path}`` starts with the specified substing ``{expected_value}``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response body parameter should start with: [data][attributes][name] Comp``
+ ...
+ ... The example above checks that ``name`` parameter starts with 'comp', e.g. as in Computer.
+ [Arguments] ${json_path} ${expected_value}
+ ${data}= Get Value From Json ${response_body} ${json_path}
+ ${data}= Convert To String ${data}
+ ${data}= Replace String ${data} ' ${EMPTY}
+ ${data}= Replace String ${data} [ ${EMPTY}
+ ${data}= Replace String ${data} ] ${EMPTY}
+ Should Start With ${data} ${expected_value} msg=Body parameter:'${json_path}' does not start with:'${expected_value}'
+
+Array in response should contain property with value:
+ [Documentation] This keyword checks is the specified array (usually error array) ``{json_path} `` contains the specified property name ``{expected_property}`` with the specified value ``{expected_value}``.
+ ...
+ ... This keyword can be used in negative tests where you expect more than one error to be returned by the request. But it can also be used for checking that property-value combination exists in an array element of the array.
+ ...
+ ... *Example:*
+ ...
+ ... ``Array in response should contain property with value: [errors] detail iso2Code => This field is missing.``
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${value}= Get Value From Json ${list_element} ${expected_property}
+ ${value}= Convert To String ${value}
+ ${value}= Replace String ${value} ' ${EMPTY}
+ ${value}= Replace String ${value} [ ${EMPTY}
+ ${value}= Replace String ${value} ] ${EMPTY}
+ ${result}= Evaluate '${value}' == '${expected_value}'
+ IF ${result} Exit For Loop
+ END
+ Should Be Equal As Strings ${result} True Property:'${expected_property}' with value '${expected_value}' was not found in the array:'${json_path}'
+
+Cleanup existing customer addresses:
+ [Documentation] This keyword deletes any and all addresses customer with the specified customer reference has.
+ ...
+ ... Before using this method you should get customer token and set it into the headers with the help of ``I get access token for the customer:`` and ``I set Headers:``
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup existing customer addresses: ${yves_user.reference}``
+ [Arguments] ${customer_reference}
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/customers/${customer_reference}/addresses headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=200 verify=${verify_ssl}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ Set Variable ${response_body} ${response_body}
+ Set Variable ${response} ${response}
+ Should Be Equal As Strings ${response.status_code} 200 Could not get customer addresses
+ @{data}= Get Value From Json ${response_body} [data]
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${address_uid}= Get Value From Json ${list_element} [id]
+ ${address_uid}= Convert To String ${address_uid}
+ ${address_uid}= Replace String ${address_uid} ' ${EMPTY}
+ ${address_uid}= Replace String ${address_uid} [ ${EMPTY}
+ ${address_uid}= Replace String ${address_uid} ] ${EMPTY}
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/customers/${customer_reference}/addresses/${address_uid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response_delete.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ Set Variable ${response_delete} ${response_delete}
+ Should Be Equal As Strings ${response_delete.status_code} 204 Could not delete a customer address
+ END
+
+Find or create customer cart
+ [Documentation] This keyword creates or retrieves cart (in gross price mode and with eur currency) for the current customer token. This keyword sets ``{cart_id} `` variable
+ ... and it can be re-used by the keywords that follow this keyword in the test
+ ...
+ ... This keyword does not accept any arguments. Makes GET request in order to fetch cart for the customer or creates it otherwise.
+ ...
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/carts headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ ${response_headers}= Set Variable ${response.headers}
+ Set Test Variable ${response_headers} ${response_headers}
+ @{data}= Get Value From Json ${response_body} [data]
+ ${cart_id}= Get Value From Json ${response_body} [data][0][id]
+ ${hasCart} Run Keyword and return status Should not be empty ${cart_id}
+ IF ${hasCart}
+ ${carts_number}= Get Length @{data}
+ FOR ${index} IN RANGE 0 ${carts_number}
+ ${cart}= Get From List @{data} ${index}
+ ${cart_id}= Get Value From Json ${cart} [id]
+ ${cart_id}= Convert To String ${cart_id}
+ ${cart_id}= Replace String ${cart_id} ' ${EMPTY}
+ ${cart_id}= Replace String ${cart_id} [ ${EMPTY}
+ ${cart_id}= Replace String ${cart_id} ] ${EMPTY}
+ ${cart_mode}= Get Value From Json ${cart} [attributes][priceMode]
+ ${cart_mode}= Convert To String ${cart_mode}
+ ${cart_mode}= Replace String ${cart_mode} ' ${EMPTY}
+ ${cart_mode}= Replace String ${cart_mode} [ ${EMPTY}
+ ${cart_mode}= Replace String ${cart_mode} ] ${EMPTY}
+ ${cart_currency}= Get Value From Json ${cart} [attributes][currency]
+ ${cart_currency}= Convert To String ${cart_currency}
+ ${cart_currency}= Replace String ${cart_currency} ' ${EMPTY}
+ ${cart_currency}= Replace String ${cart_currency} [ ${EMPTY}
+ ${cart_currency}= Replace String ${cart_currency} ] ${EMPTY}
+ ${expected_cart_found}= Run Keyword And Return Status Should Be True '${cart_mode}' == 'GROSS_MODE' and '${cart_currency}' == 'EUR'
+ IF ${expected_cart_found} == 1
+ Set Test Variable ${cart_id} ${cart_id}
+ BREAK
+ END
+ IF '${env}' in ['api_b2c','api_mp_b2c']
+ Set Test Variable ${cart_id} ${cart_id}
+ BREAK
+ END
+ IF ${index} < ${carts_number}-1 and ${expected_cart_found} == 0
+ Continue For Loop
+ ELSE
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "dummyCart${random}"}}}
+ Save value to a variable: [data][id] cart_id
+ END
+ END
+ ELSE
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "dummyCart${random}"}}}
+ Save value to a variable: [data][id] cart_id
+ END
+
+Create empty customer cart:
+ [Documentation] This keyword creates cart for the current customer token. This keyword sets ``{cart_id} `` variable
+ ... and it can be re-used by the keywords that follow this keyword in the test.
+ ...
+ ... Note: work only for registered customers. For guest users use ``Create a guest cart:``
+ ...
+ ... *Example:*
+ ...
+ ... ``Create empty customer cart: ${mode.gross} ${currency.eur.code} ${store.de} cart_rules``
+ ...
+ [Arguments] ${price_mode} ${currency_code} ${store_code} ${cart_name}
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${price_mode}","currency": "${currency_code}","store": "${store_code}","name": "${cart_name}-${random}"}}}
+ Save value to a variable: [data][id] cart_id
+
+Get ETag header value from cart
+ [Documentation] This keyword first retrieves cart for the current customer token.
+ ... and then It gets the Etag header value and saves it into the test variable ``{Etag}``, which can then be used within the scope of the test where this keyword was called.
+ ...
+ ... and it can be re-used by the keywords that follow this keyword in the test
+ ... This keyword does not accept any arguments. This keyword is used for removing unused/unwanted (ex. W/"") characters from ETag header value.
+ ${response}= I send a GET request: /carts
+ ${Etag}= Get Value From Json ${response_headers} [ETag]
+ ${Etag}= Convert To String ${Etag}
+ ${Etag}= Replace String ${Etag} ' ${EMPTY}
+ ${Etag}= Replace String ${Etag} [ ${EMPTY}
+ ${Etag}= Replace String ${Etag} ] ${EMPTY}
+ ${Etag}= Replace String ${Etag} W ${EMPTY}
+ ${Etag}= Replace String ${Etag} / ${EMPTY}
+ ${Etag}= Replace String ${Etag} " ${EMPTY}
+ Set Test Variable ${Etag}
+ RETURN ${Etag}
+
+Create a guest cart:
+ [Documentation] This keyword creates guest cart and sets ``{x_anonymous_customer_unique_id}`` that specify guest reference
+ ... and ``{guest_cart_id}`` that specify guest cart, variables
+ ... can be re-used by the keywords that follow this keyword in the test
+ ...
+ ... This keyword does not accept any arguments. Makes POST request in order to create cart for the guest.
+ ... *Example:*
+ ...
+ ... ``Create guest cart: ${random} ${concrete_product_with_concrete_product_alternative_sku} 1``
+ [Arguments] ${x_anonymous_customer_unique_id} ${product_sku} ${product_quantity}
+ Set Test Variable ${x_anonymous_customer_unique_id} ${x_anonymous_customer_unique_id}
+ I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id} Content-Type=${default_header_content_type}
+ ${response}= I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${product_sku}","quantity": ${product_quantity}}}}
+ Save value to a variable: [data][id] guest_cart_id
+ Log x_anonymous_customer_unique_id:${x_anonymous_customer_unique_id} guest_cart_id:${guest_cart_id}
+
+Cleanup all items in the cart:
+ [Documentation] This keyword deletes any and all items in the given cart uid.
+ ...
+ ... Before using this method you should get customer token and set it into the headers with the help of ``I get access token for the customer:`` and ``I set Headers:``
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup items in the cart: ${cart_id}``
+ [Arguments] ${cart_id}
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/carts/${cart_id} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} params=include=items,bundle-items expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ @{included}= Get Value From Json ${response_body} [included]
+ ${list_not_empty}= Get length ${included}
+ IF ${list_not_empty} > 0
+ ${list_length}= Get length @{included}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{included} ${index}
+ ${cart_item_uid}= Get Value From Json ${list_element} [attributes][groupKey]
+ ${cart_item_sku}= Get Value From Json ${list_element} [attributes][sku]
+ ${cart_item_uid}= Convert To String ${cart_item_uid}
+ ${cart_item_uid}= Replace String ${cart_item_uid} ' ${EMPTY}
+ ${cart_item_uid}= Replace String ${cart_item_uid} [ ${EMPTY}
+ ${cart_item_uid}= Replace String ${cart_item_uid} ] ${EMPTY}
+ ${cart_item_sku}= Convert To String ${cart_item_sku}
+ ${cart_item_sku}= Replace String ${cart_item_sku} ' ${EMPTY}
+ ${cart_item_sku}= Replace String ${cart_item_sku} [ ${EMPTY}
+ ${cart_item_sku}= Replace String ${cart_item_sku} ] ${EMPTY}
+ TRY
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/carts/${cart_id}/items/${cart_item_uid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ EXCEPT
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/carts/${cart_id}/items/${cart_item_sku} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ END
+ END
+ END
+
+Cleanup all customer carts
+ [Documentation] This keyword deletes all customer carts
+ ...
+ ... Before using this method you should get customer token and set it into the headers with the help of ``I get access token for the customer:`` and ``I set Headers:``
+ ... This keyword does not accept any arguments.
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup all customer carts``
+ IF '${env}' not in ['api_b2c','api_mp_b2c']
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "dummyCart-${{random.randint(0, 100)}}${random}"}}}
+ Save value to a variable: [data][id] cart_id
+ END
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/carts headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} params=include=items,bundle-items expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ @{data}= Get Value From Json ${response_body} [data]
+ ${list_not_empty}= Get length ${data}
+ IF ${list_not_empty} > 0
+ ${list_length}= Get Length @{data}
+ FOR ${index} IN RANGE 0 ${list_length}-1
+ ${list_element}= Get From List @{data} ${index}
+ ${cart_uuid}= Get Value From Json ${list_element} [id]
+ ${cart_uuid}= Convert To String ${cart_uuid}
+ ${cart_uuid}= Replace String ${cart_uuid} ' ${EMPTY}
+ ${cart_uuid}= Replace String ${cart_uuid} [ ${EMPTY}
+ ${cart_uuid}= Replace String ${cart_uuid} ] ${EMPTY}
+ IF '${env}' not in ['api_b2c','api_mp_b2c']
+ IF '${cart_uuid}' == '${cart_id}'
+ Continue For Loop
+ ELSE
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/carts/${cart_uuid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ END
+ ELSE
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/carts/${cart_uuid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ END
+ END
+ END
+
+Cleanup all items in the guest cart:
+ [Documentation] This keyword deletes any and all items in the given GUEST cart uid.
+ ...
+ ... Before using this method you should set any value as X-Anonymous-Customer-Unique-Id into the headers with the help of ``I set Headers:``
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup all items in the guest cart: ${cart_id}``
+ [Arguments] ${cart_id}
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/guest-carts/${cart_id} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} params=include=guest-cart-items,bundle-items expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ @{included}= Get Value From Json ${response_body} [included]
+ ${list_not_empty}= Get length ${included}
+ IF ${list_not_empty} > 0
+ ${list_length}= Get length @{included}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{included} ${index}
+ ${cart_item_uid}= Get Value From Json ${list_element} [id]
+ ${cart_item_uid}= Convert To String ${cart_item_uid}
+ ${cart_item_uid}= Replace String ${cart_item_uid} ' ${EMPTY}
+ ${cart_item_uid}= Replace String ${cart_item_uid} [ ${EMPTY}
+ ${cart_item_uid}= Replace String ${cart_item_uid} ] ${EMPTY}
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/guest-carts/${cart_id}/guest-cart-items/${cart_item_uid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ END
+ END
+Cleanup all availability notifications:
+ [Documentation] This keyword deletes any and all availability notifications related to the given customer reference.
+ ...
+ ... Before using this method you should get customer token and set it into the headers with the help of ``I get access token for the customer:`` and ``I set Headers:``
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup all availability notifications in the guest cart: ${yves_user.reference}``
+ [Arguments] ${yves_user.reference}
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/customers/${yves_user.reference}/availability-notifications headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ @{data}= Get Value From Json ${response_body} [data]
+ ${list_not_empty}= Get length ${data}
+ IF ${list_not_empty} > 0
+ ${list_length}= Get Length @{data}
+ ${list_length}= Convert To Integer ${list_length}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${availability_notification_id}= Get Value From Json ${list_element} [id]
+ ${availability_notification_id}= Convert To String ${availability_notification_id}
+ ${availability_notification_id}= Replace String ${availability_notification_id} ' ${EMPTY}
+ ${availability_notification_id}= Replace String ${availability_notification_id} [ ${EMPTY}
+ ${availability_notification_id}= Replace String ${availability_notification_id} ] ${EMPTY}
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/availability-notifications/${availability_notification_id} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204 verify=${verify_ssl}
+ END
+ END
+
+Get the first company user id and its' customer email
+ [Documentation] This keyword sends the GET request to the ``/company-users?include=customers`` endpoint and returns first available company user id and its' customer email in
+ ... ``{companyUserId}`` and ``{companyUserEmail}`` variables.
+ ... If the fist company user is anne.boleyn@spryker.com - the next one will be taken and Anna is a 'BoB' user
+ ...
+ I send a GET request: /company-users?include=customers
+ Save value to a variable: [data][0][id] companyUserId
+ Save value to a variable: [included][0][attributes][email] companyUserEmail
+ IF '${companyUserEmail}' == 'anne.boleyn@spryker.com'
+ Save value to a variable: [included][1][attributes][email] companyUserEmail
+ Save value to a variable: [data][1][id] companyUserId
+ END
+
+Array element should contain nested array at least once:
+ [Documentation] This keyword checks whether the array ``{parent_array}`` that is present in the ``{response_body}`` test variable contains an array ``{expected_nested_array}`` at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``Array element should contain nested array at least once: [data] [relationships]``
+ ...
+ [Arguments] ${parent_array} ${expected_nested_array}
+ @{data}= Get Value From Json ${response_body} ${parent_array}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ ${expected_nested_array}= Replace String ${expected_nested_array} [ ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ] ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ' ${EMPTY}
+ ${expected_nested_array}= Create List ${expected_nested_array}
+ FOR ${index} IN RANGE 0 ${list_length}
+ @{list_element}= Get From List @{data} ${index}
+ ${result}= Run Keyword And Ignore Error List Should Contain Sub List ${list_element} ${expected_nested_array}
+ IF 'PASS' in $result Exit For Loop
+ IF ${index} == ${list_length}-1
+ Fail expected '${expected_nested_array}' array is not present in '@{data}'
+ END
+ IF 'FAIL' in $result Continue For Loop
+ END
+
+Array element should contain property with value at least once:
+ [Documentation] This keyword checks that element in the array specified as ``{json_path}`` contains the specified property ``{expected_property}`` with the specified value ``{expected_value}`` at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``And Array element should contain property with value at least once: [data][0][attributes][categoryTreeFilter] docCount ${${category_lvl2.qty}}``
+ ...
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${result}= Run Keyword And Ignore Error Dictionary Should Contain Item ${list_element} ${expected_property} ${expected_value}
+ IF 'PASS' in $result Exit For Loop
+ IF ${index} == ${list_length}-1
+ Fail expected '${expected_property}' with value '${expected_value}' is not present in '{data}' but should
+ END
+ IF 'FAIL' in $result Continue For Loop
+ END
+
+Array element should contain property or array value at least once:
+ [Documentation] Verifies that at least one element in the array at JSON path ``{json_path}`` has the property ``{expected_property}`` whose value is either:
+ ... - a scalar equal (as string) to ``{expected_value}``, or
+ ... - a list/tuple containing ``{expected_value}``.
+ ... *Usage:*
+ ... ``And Array element should contain property or array value at least once [data][0][attributes][valueFacets] activeValue ${brand_1}``
+ ... ``And Array element should contain property or array value at least once [data][0][attributes][valueFacets] activeValue ${brand_2}``
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{elements}= Get Value From Json ${response_body} ${json_path}
+ ${count}= Get Length @{elements}
+
+ FOR ${idx} IN RANGE 0 ${count}
+ ${elem}= Get From List @{elements} ${idx}
+ Dictionary Should Contain Key ${elem} ${expected_property}
+ ${value}= Get From Dictionary ${elem} ${expected_property}
+
+ ${is_list}= Run Keyword And Return Status Should Be True isinstance(${value}, (list, tuple))
+ IF ${is_list}
+ ${match}= Run Keyword And Return Status Should Contain ${value} ${expected_value}
+ ELSE
+ ${match}= Run Keyword And Return Status Should Be Equal As Strings ${value} ${expected_value}
+ END
+
+ IF ${match}
+ Exit For Loop
+ END
+
+ IF ${idx} == ${count} - 1
+ Fail Expected property '${expected_property}' with value '${expected_value}' was not found in any element of array at path '${json_path}'
+ END
+ END
+
+Each array element should contain property with value:
+ [Documentation] This keyword checks that each element in the array at JSON path ``{json_path}`` contains the specified property ``{expected_property}`` with the specified value ``{expected_value}``, comparing both as strings.
+ ... *Example:* ``Each array element should contain property with value [data][0][attributes][valueFacets] activeValue None``
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${element}= Get From List @{data} ${index}
+ Dictionary Should Contain Key ${element} ${expected_property}
+ ${actual}= Get From Dictionary ${element} ${expected_property}
+ ${actual_str}= Convert To String ${actual}
+ ${expected_str}= Convert To String ${expected_value}
+ Should Be Equal ${actual_str} ${expected_str} ignore_case=True msg=Property '${expected_property}' with value '${expected_value}' is not present in the array at JSON path '${json_path}' but should be.
+ END
+
+Nested array element should contain sub-array at least once:
+ [Documentation] This keyword checks that nested array ``{parent_array}`` in the array specified as ``{json_path}`` contains the specified sub-array ``{expected_nested_array}`` at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``And Nested array element should contain sub-array at least once: [data] [relationships] company-role``
+ ...
+ [Arguments] ${json_path} ${parent_array} ${expected_nested_array}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${result}= Set Variable 'FALSE'
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ ${expected_nested_array}= Replace String ${expected_nested_array} [ ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ] ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ' ${EMPTY}
+ ${expected_nested_array}= Create List ${expected_nested_array}
+ FOR ${index} IN RANGE 0 ${list_length}
+ IF 'PASS' in $result BREAK
+ ${list_element}= Get From List @{data} ${index}
+ @{list_element2}= Get Value From Json ${list_element} ${parent_array}
+ @{list_element}= Get From List ${list_element2} 0
+ ${result}= Run Keyword And Ignore Error List Should Contain Sub List ${list_element} ${expected_nested_array} ignore_case=True
+ IF 'PASS' in $result Exit For Loop
+ IF ${index} == ${list_length}-1
+ Fail expected '${expected_nested_array}' array is not present in '@{data}'
+ END
+ IF 'FAIL' in $result Continue For Loop
+ END
+
+Nested array element should contain sub-array with property and value at least once:
+ [Documentation] This keyword checks whether the nested array ``{expected_nested_array}`` that is present in the parent array ``{parent_array}`` under the json path ``{json_path}`` contains propery ``{expected_property}`` with value ``{expected_value}`` at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] configuration {"time_of_day":"4"}``
+ ...
+ [Arguments] ${json_path} ${parent_array} ${expected_nested_array} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${result}= Set Variable 'FALSE'
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ ${expected_nested_array}= Replace String ${expected_nested_array} [ ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ] ${EMPTY}
+ ${expected_nested_array}= Replace String ${expected_nested_array} ' ${EMPTY}
+ ${expected_nested_array}= Convert To String ${expected_nested_array}
+ FOR ${index} IN RANGE 0 ${list_length}
+ IF 'PASS' in $result BREAK
+ ${parent_array_element}= Get From List @{data} ${index}
+ @{actual_parent_element}= Get Value From Json ${parent_array_element} ${parent_array}
+ # Log List @{actual_parent_element}
+ ${actual_nested_array}= Get From List ${actual_parent_element} 0
+ ${actual_property_array}= Get Value From Json ${actual_nested_array} ${expected_nested_array}
+ ${actual_property_value}= Get From List ${actual_property_array} 0
+ ${actual_property_value}= Get Value From Json ${actual_property_value} ${expected_property}
+ ${actual_property_value}= Convert To String ${actual_property_value}
+ ${actual_property_value}= Replace String ${actual_property_value} ' ${EMPTY}
+ ${actual_property_value}= Replace String ${actual_property_value} [ ${EMPTY}
+ ${actual_property_value}= Replace String ${actual_property_value} ] ${EMPTY}
+ ${result}= Run Keyword And Ignore Error Should Contain ${actual_property_value} ${expected_value} ignore_case=True
+ IF 'PASS' in $result BREAK
+ IF ${index} == ${list_length}-1
+ Fail expected '${expected_property}' with value '${expected_value}' is not present in '${expected_nested_array}' but should
+ END
+ IF 'FAIL' in $result Continue For Loop
+ END
+
+Array element should contain nested array with property and value at least once:
+ [Documentation] This keyword checks whether the array ``{nested_array}`` that is present in the parent array ``{json_path}`` contains propery ``{expected_property}`` with value ``{expected_value}`` at least once.
+ ...
+ ... *Example:*
+ ...
+ ... ``And Array element should contain nested array with property and value at least once: [data][0][attributes][categoryTreeFilter] [children] docCount ${category_lvl2.qty}``
+ ...
+ [Arguments] ${json_path} ${nested_array} ${expected_property} ${expected_value}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length1}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ ${result}= Set Variable 'FALSE'
+ FOR ${index1} IN RANGE 0 ${list_length1}
+ IF 'PASS' in $result BREAK
+ ${list_element}= Get From List @{data} ${index1}
+ @{list_element2}= Get Value From Json ${list_element} ${nested_array}
+ ${list_length2}= Get Length @{list_element2}
+ FOR ${index2} IN RANGE 0 ${list_length2}
+ ${list_element}= Get From List @{list_element2} ${index2}
+ ${list_element}= Get Value From Json ${list_element} ${expected_property}
+ ${list_element}= Convert To String ${list_element}
+ ${list_element}= Replace String ${list_element} ' ${EMPTY}
+ ${list_element}= Replace String ${list_element} [ ${EMPTY}
+ ${list_element}= Replace String ${list_element} ] ${EMPTY}
+ ${result}= Run Keyword And Ignore Error Should Contain ${list_element} ${expected_value} ignore_case=True
+ IF 'PASS' in $result BREAK
+ IF ${index1} == ${list_length1}-1 and ${index2} == ${list_length2}-1
+ Fail expected '${expected_property}' with value '${expected_value}' is not present in '${nested_array}' but should
+ END
+ IF 'FAIL' in $result Continue For Loop
+ END
+ END
+
+Response should contain a nested array of a certain size at least once:
+ [Documentation] This keyword checks whether the nested array ``{nested_array}`` present at the JSON path ``{json_path}`` in the ``{response_body}`` test variable contains at least one element whose size is at least ``{expected_size}``.
+ ...
+ ... *Example:*
+ ...
+ ... ``Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values 5``
+ [Arguments] ${json_path} ${nested_array} ${expected_size}
+ @{data}= Get Value From Json ${response_body} ${json_path}
+ ${list_length}= Get Length @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${item}= Get From List @{data} ${index}
+ @{sub_array}= Get Value From Json ${item} ${nested_array}
+ ${sub_length}= Get Length @{sub_array}
+ ${sub_length}= Convert To Integer ${sub_length}
+ ${expected_size}= Convert To Integer ${expected_size}
+ ${result}= Run Keyword And Ignore Error Should Be True ${sub_length} == ${expected_size}
+ IF 'PASS' in ${result}
+ Exit For Loop
+ END
+ IF ${index} == ${list_length}-1
+ Fail expected nested array '@{nested_array}' with size '${expected_size}' is not present in '[data]'
+ END
+ IF 'FAIL' in ${result}
+ Continue For Loop
+ END
+ END
+
+Response body array element should contain property with value at least once:
+ [Documentation] This keyword checks that in the response saved in ``{response_body}``,
+ ... the array at JSON path ``{json_path}`` has at least one element whose
+ ... property (itself at JSON path ``{property_path}``) equals ``{expected_value}``
+ ... *Example:*
+ ...
+ ... ``Response body array element should contain property with value at least once: [data] [attributes][name] GTC``
+ [Arguments] ${json_path} ${property_path} ${expected_value}
+ @{elements}= Get Value From Json ${response_body} ${json_path}
+ ${length}= Get Length @{elements}
+ ${result}= Set Variable FALSE
+ FOR ${i} IN RANGE 0 ${length}
+ ${elem}= Get From List @{elements} ${i}
+ ${actual}= Get Value From Json ${elem} ${property_path}
+ ${actual}= Convert To String ${actual}
+ ${actual}= Replace String ${actual} ' ${EMPTY}
+ ${actual}= Replace String ${actual} [ ${EMPTY}
+ ${actual}= Replace String ${actual} ] ${EMPTY}
+ ${check}= Run Keyword And Ignore Error Should Be Equal As Strings
+ ... ${actual} ${expected_value} ignore_case=True
+ IF 'PASS' in ${check}
+ ${result}= Set Variable TRUE
+ Exit For Loop
+ END
+ END
+ Should Be Equal As Strings ${result} TRUE
+ ... Property '${property_path}' with value '${expected_value}' was not found in array at '${json_path}'
+
+Array element should contain property with value greater than at least once:
+ [Documentation] Checks that within the array at ${json_path}, at least one element has
+ ... property ${expected_property} whose numeric value is > ${expected_value}.
+ ... Elements lacking the property are ignored.
+ ...
+ ... *Example:*
+ ... Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{arr}= Get Value From Json ${response_body} ${json_path}
+ ${length}= Get Length @{arr}
+ Should Be True ${length} > 0 No elements found at path '${json_path}'.
+
+ ${hit}= Set Variable ${False}
+ FOR ${i} IN RANGE 0 ${length}
+ ${el}= Get From List @{arr} ${i}
+ ${got}= Run Keyword And Ignore Error Get From Dictionary ${el} ${expected_property}
+ ${status}= Set Variable ${got}[0]
+ ${raw}= Set Variable ${got}[1]
+ IF '${status}' == 'PASS'
+ # Coerce both sides to numbers (int/float or numeric strings)
+ ${act_conv}= Run Keyword And Ignore Error Convert To Number ${raw}
+ IF '${act_conv}[0]' == 'PASS'
+ ${actual}= Set Variable ${act_conv}[1]
+ ELSE
+ ${actual}= Evaluate float(${raw})
+ END
+ ${exp_conv}= Run Keyword And Ignore Error Convert To Number ${expected_value}
+ IF '${exp_conv}[0]' == 'PASS'
+ ${expected}= Set Variable ${exp_conv}[1]
+ ELSE
+ ${expected}= Evaluate float(${expected_value})
+ END
+
+ IF ${actual} > ${expected}
+ ${hit}= Set Variable ${True}
+ Exit For Loop
+ END
+ END
+ END
+ Should Be True ${hit} No element at '${json_path}' has property '${expected_property}' greater than '${expected_value}'.
+
+Array element should contain property with value less than at least once:
+ [Documentation] Checks that within the array at ${json_path}, at least one element has
+ ... property ${expected_property} whose numeric value is < ${expected_value}.
+ ... Elements lacking the property are ignored.
+ ...
+ ... *Example:*
+ ... Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] ORIGINAL 200000
+ [Arguments] ${json_path} ${expected_property} ${expected_value}
+ @{arr}= Get Value From Json ${response_body} ${json_path}
+ ${length}= Get Length @{arr}
+ Should Be True ${length} > 0 No elements found at path '${json_path}'.
+
+ ${hit}= Set Variable ${False}
+ FOR ${i} IN RANGE 0 ${length}
+ ${el}= Get From List @{arr} ${i}
+ ${got}= Run Keyword And Ignore Error Get From Dictionary ${el} ${expected_property}
+ ${status}= Set Variable ${got}[0]
+ ${raw}= Set Variable ${got}[1]
+ IF '${status}' == 'PASS'
+ ${act_conv}= Run Keyword And Ignore Error Convert To Number ${raw}
+ IF '${act_conv}[0]' == 'PASS'
+ ${actual}= Set Variable ${act_conv}[1]
+ ELSE
+ ${actual}= Evaluate float(${raw})
+ END
+ ${exp_conv}= Run Keyword And Ignore Error Convert To Number ${expected_value}
+ IF '${exp_conv}[0]' == 'PASS'
+ ${expected}= Set Variable ${exp_conv}[1]
+ ELSE
+ ${expected}= Evaluate float(${expected_value})
+ END
+
+ IF ${actual} < ${expected}
+ ${hit}= Set Variable ${True}
+ Exit For Loop
+ END
+ END
+ END
+ Should Be True ${hit} No element at '${json_path}' has property '${expected_property}' less than '${expected_value}'.
+
+Get company user id by customer reference:
+ [Documentation] This keyword sends the GET request to the ``/company-users?include=customers`` endpoint and returns company user id by customer reference. Sets variable : ``{companyUserId}``
+ ...
+ ... *Example:*
+ ... ``Get company user id by customer reference: ${yves_fifth_user.reference}``
+ ...
+ [Arguments] ${customer_reference}
+ I send a GET request: /company-users?include=customers
+ @{data}= Get Value From Json ${response_body} [data]
+ ${list_length}= Get Length @{data}
+ # ${log_list}= Log List @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${company_user_id}= Get Value From Json ${list_element} id
+ ${company_user_id}= Convert To String ${company_user_id}
+ ${company_user_id}= Replace String ${company_user_id} ' ${EMPTY}
+ ${company_user_id}= Replace String ${company_user_id} [ ${EMPTY}
+ ${company_user_id}= Replace String ${company_user_id} ] ${EMPTY}
+ Set Test Variable ${companyUserId} ${company_user_id}
+ @{list_element2}= Get Value From Json ${list_element} relationships
+ ${company_user_customer_id}= Get Value From Json @{list_element2} customers.data[0].id
+ ${company_user_customer_id}= Convert To String ${company_user_customer_id}
+ ${company_user_customer_id}= Replace String ${company_user_customer_id} ' ${EMPTY}
+ ${company_user_customer_id}= Replace String ${company_user_customer_id} [ ${EMPTY}
+ ${company_user_customer_id}= Replace String ${company_user_customer_id} ] ${EMPTY}
+ IF '${company_user_customer_id}' == '${customer_reference}' BREAK
+ IF ${index} == ${list_length}-1
+ Fail expected customer reference '${customer_reference}' is not present in '@{data}' but should
+ END
+ END
+
+Cleanup all existing shopping lists
+ [Documentation] This keyword deletes all customer shopping lists
+ ...
+ ... Before using this method you should get customer token and set it into the headers with the help of ``I get access token for the customer:`` and ``I set Headers:``
+ ... This keyword does not accept any arguments.
+ ...
+ ... *Example:*
+ ...
+ ... ``Cleanup all existing shopping lists``
+ Setup_api_host_if_undefined
+ ${response}= GET On Session ${api_session} ${current_url}/shopping-lists headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} params=include=items,bundle-items expected_status=200 verify=${verify_ssl}
+ ${response.status_code}= Set Variable ${response.status_code}
+ IF ${response.status_code} != 204
+ TRY
+ ${response_body}= Set Variable ${response.json()}
+ EXCEPT
+ ${content_type}= Get From Dictionary ${response.headers} content-type
+ Fail Got: '${response.status_code}' status code on: '${response.url}' with reason: '${response.reason}'. Response content type: '${content_type}'. Details: '${response.content}'
+ END
+ END
+ IF ${response.status_code} == 204
+ ${response_body}= Set Variable ${EMPTY}
+ END
+ @{data}= Get Value From Json ${response_body} [data]
+ ${list_not_empty}= Get length ${data}
+ IF ${list_not_empty} > 0
+ ${list_length}= Get Length @{data}
+ FOR ${index} IN RANGE 0 ${list_length}
+ ${list_element}= Get From List @{data} ${index}
+ ${shopping_list_uuid}= Get Value From Json ${list_element} [id]
+ ${shopping_list_uuid}= Convert To String ${shopping_list_uuid}
+ ${shopping_list_uuid}= Replace String ${shopping_list_uuid} ' ${EMPTY}
+ ${shopping_list_uuid}= Replace String ${shopping_list_uuid} [ ${EMPTY}
+ ${shopping_list_uuid}= Replace String ${shopping_list_uuid} ] ${EMPTY}
+ ${response_delete}= DELETE On Session ${api_session} ${current_url}/shopping-lists/${shopping_list_uuid} headers=${headers} timeout=${api_timeout} allow_redirects=${default_allow_redirects} auth=${default_auth} expected_status=204
+ END
+ END
+
+I get access token by user credentials:
+ [Documentation] This is a helper keyword which helps get access token for future use in the headers of the following requests.
+ ...
+ ... It gets the token for the specified user ``{email}`` and saves it into the test variable ``{token}``, which can then be used within the scope of the test where this keyword was called.
+ ... After the test ends the ``{token}`` variable is cleared. This keyword needs to be called separately for each test where you expect to need a customer token.
+ ...
+ ... The password in this case is not passed to the keyword and the default password stored in ``{default_password}`` will be used when getting token.
+ ...
+ ... *Example:*
+ ...
+ ... ``I get access token by user credentials: ${zed_admin.email}``
+ [Arguments] ${email} ${password}=${default_password}
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request: /token {"grantType": "${grant_type.password}","username": "${email}","password": "${password}"}
+ Save value to a variable: [access_token] token
+ RETURN ${token}
+
+Switch to Glue
+ Remove Tags *
+ Set Tags glue
+ Overwrite api variables
+ Reset API Headers
+
+Switch to BAPI
+ Remove Tags *
+ Set Tags bapi
+ Overwrite api variables
+ Reset API Headers
+
+*** Keywords ***
+Array Element Should Contain Nested Property With Value At Least Once
+ [Arguments] ${json_path} ${nested_path} ${property} ${expected_value}
+ ${matches}= Get Value From Json ${response_body} ${json_path}
+ ${exists}= Evaluate
+ ... any(item.get('${nested_path}', {}).get('${property}', None) == ${expected_value} for item in ${matches})
+ Should Be True ${exists} Expected property '${property}' with value '${expected_value}' not found in any array element.
+
+Delete dynamic customer via API
+ [Arguments] ${customer_email}=${EMPTY}
+
+ ${dynamic_customer_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_customer}
+
+ IF '${customer_email}' == '${EMPTY}'
+ IF ${dynamic_customer_exists}
+ VAR ${customer_email} ${dynamic_customer}
+ ELSE
+ Log message=No dynamic (doesn't exist) or static customer was provided for deletion level=INFO
+ RETURN
+ END
+ END
+ Set Tags glue
+ API_test_setup
+ I get access token for the customer: ${customer_email}
+ I set Headers: Authorization=${token}
+ I send a GET request: /customers
+ Save value to a variable: [data][0][id] userId
+ I send a DELETE request: /customers/${userId}
+ Response status code should be: 204
+ Remove Tags glue
+
+To JSON Boolean
+ [Arguments] ${value}
+ ${is_true}= Run Keyword And Return Status Should Be True ${value}
+ IF ${is_true}
+ RETURN true
+ ELSE
+ RETURN false
+ END
+
+Get Json Value
+ [Arguments] ${body} ${path}
+ ${value}= Get Value ${body} ${path}
+ RETURN ${value}
+
+Response body parameter should be either:
+ [Arguments] ${json_path_1} ${json_path_2} ${expected}
+ ${status_1}= Run Keyword And Return Status Response body parameter should be: ${json_path_1} ${expected}
+ ${status_2}= Run Keyword And Return Status Response body parameter should be: ${json_path_2} ${expected}
+ IF not ${status_1} and not ${status_2}
+ Fail Neither '${json_path_1}' nor '${json_path_2}' equals expected value ${expected}.
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/common/common_mp.robot b/atest/testdata/performance/resources/common/common_mp.robot
new file mode 100644
index 0000000..cdbbb1b
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common_mp.robot
@@ -0,0 +1,322 @@
+*** Settings ***
+Resource common_ui.robot
+Resource ../pages/mp/mp_login_page.robot
+
+*** Variables ***
+${mp_user_menu_button} xpath=//button[contains(@class,'spy-user-menu__action')]
+${mp_navigation_slider_menu} xpath=//spy-navigation
+${mp_submit_button} xpath=(//spy-drawer-wrapper)[position()=last()]//button[@type='submit' and not(.//text()[normalize-space()='Back'])] | //web-mp-form//button[@type='submit' and not(.//text()[normalize-space()='Back'])]
+${mp_items_table} xpath=//nz-table-inner-default//table
+${mp_search_box} xpath=//spy-table//input[contains(@placeholder,'Search')]
+${mp_close_drawer_button} xpath=(//button[contains(@class,'spy-drawer-wrapper__action--close')])[1]
+${spinner_loader} xpath=//span[contains(@class,'ant-spin-dot')]
+${mp_success_flyout} xpath=//span[contains(@class,'alert')][contains(@class,'icon')][contains(@class,'success')]
+${mp_error_flyout} xpath=//span[contains(@class,'alert')][contains(@class,'icon')][contains(@class,'error')]
+${mp_notification_wrapper} xpath=//spy-notification-wrapper
+${mp_loading_icon} xpath=//span[contains(@class,'spin-dot') and not(ancestor::div[contains(@style,'hidden')])]
+
+*** Keywords ***
+MP: login on MP with provided credentials:
+ [Arguments] ${email} ${password}=${default_password}
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ MP: go to URL: /
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${is_login_page}= Run Keyword And Ignore Error Page Should Contain Element ${mp_user_name_field} timeout=10ms
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_login_page
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ MP: go to URL: /
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${mp_user_name_field}
+ ${email_value}= Convert To Lower Case ${email}
+ IF '+merchant+' in '${email_value}' VAR ${password} ${default_secure_password}
+ Type Text ${mp_user_name_field} ${email}
+ Type Text ${mp_password_field} ${password}
+ # workaround for the issue with deadlocks on concurrent login attempts
+ ${is_5xx}= Click and return True if 5xx occurred: ${mp_login_button}
+ IF ${is_5xx}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ MP: go to URL: /
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${mp_user_name_field}
+ ${email_value}= Convert To Lower Case ${email}
+ IF '+merchant+' in '${email_value}' VAR ${password} ${default_secure_password}
+ Type Text ${mp_user_name_field} ${email}
+ Type Text ${mp_password_field} ${password}
+ Click ${mp_login_button}
+ END
+ Disable Automatic Screenshots on Failure
+ ${login_success}= Run Keyword And Ignore Error Wait Until Element Is Visible ${mp_user_menu_button} MP: Login failed! Retrying... timeout=15s
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $login_success
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ MP: go to URL: /
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${mp_user_name_field}
+ Type Text ${mp_user_name_field} ${email}
+ Type Text ${mp_password_field} ${password}
+ Click ${mp_login_button}
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${mp_user_menu_button} MP: Login failed! timeout=15s
+
+MP: login on MP with provided credentials and expect error:
+ [Arguments] ${email} ${password}=${default_password}
+ Delete All Cookies
+ MP: go to URL: /
+ Delete All Cookies
+ Reload
+ Wait Until Element Is Visible ${mp_user_name_field}
+ Type Text ${mp_user_name_field} ${email}
+ Type Text ${mp_password_field} ${password}
+ Click ${mp_login_button}
+ Wait Until Element Is Visible ${mp_login_failed_message}
+ Page Should Not Contain Element ${mp_user_menu_button}
+
+MP: open navigation menu tab:
+ [Arguments] ${tabName}
+ Wait Until Element Is Visible ${mp_navigation_slider_menu}
+ Click Element by xpath with JavaScript xpath=//spy-navigation//span[contains(@class,'spy-navigation__title-text')][text()='${tabName}']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Navigation menu is not loaded
+ END
+ Wait Until Element Is Visible //div[@class='mp-layout-main-cnt__main']//span[contains(@class,'headline__title')]//*[text()='${tabName}']
+
+MP: Wait until loader is no longer visible
+ Disable Automatic Screenshots on Failure
+ ${loader_displayed}= Run Keyword And Ignore Error Element Should Be Visible ${mp_loading_icon} timeout=500ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $loader_displayed
+ TRY
+ Wait Until Element Is Not Visible ${mp_loading_icon}
+ EXCEPT
+ Take Screenshot EMBED fullPage=True
+ Fail Timeout exceeded. Loader is still displayed after ${browser_timeout}
+ END
+ ELSE
+ Run Keyword And Ignore Error Wait Until Element Is Not Visible ${mp_loading_icon} message=Timeout exceeded. Loader is still displayed after ${browser_timeout}
+ END
+
+MP: click submit button
+ [Arguments] ${timeout}=${browser_timeout}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Submit button is not loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${mp_flash_message_is_displayed}= Run Keyword And Return Status Element Should Be Visible ${mp_notification_wrapper} timeout=10ms
+ Restore Automatic Screenshots on Failure
+ IF ${mp_flash_message_is_displayed}
+ TRY
+ Set Browser Timeout 200ms
+ Remove element from HTML with JavaScript //spy-notification-wrapper
+ Set Browser Timeout ${browser_timeout}
+ EXCEPT
+ Log Flash message is not visible
+ Set Browser Timeout ${browser_timeout}
+ END
+ END
+ Wait Until Element Is Visible ${mp_submit_button} timeout=${timeout}
+ Set Browser Timeout ${browser_timeout}
+ Click ${mp_submit_button}
+ TRY
+ Repeat Keyword 5 Wait For Load State
+ Wait For Load State domcontentloaded
+ Repeat Keyword 5 Wait For Load State networkidle
+ EXCEPT
+ Log Form is not submitted
+ END
+
+MP: perform search by:
+ [Arguments] ${searchKey}
+ Wait Until Element Is Visible ${mp_search_box}
+ Clear Text ${mp_search_box}
+ Type Text ${mp_search_box} ${searchKey}
+ Keyboard Key press Enter
+ TRY
+ Wait For Response timeout=10s
+ EXCEPT
+ Log Search event is not fired
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State networkidle
+ EXCEPT
+ Log Search event is not fired
+ END
+ MP: Wait until loader is no longer visible
+
+MP: click on a table row that contains:
+ [Arguments] ${rowContent}
+ Wait Until Element Is Visible xpath=//div[@class='spy-table-column-text'][contains(text(),'${rowContent}')]/ancestor::tr[contains(@class,'ant-table-row')]
+ Click xpath=//div[@class='spy-table-column-text'][contains(text(),'${rowContent}')]/ancestor::tr[contains(@class,'ant-table-row')]
+ Wait Until Page Contains Element ${mp_close_drawer_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Drawler is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: close drawer
+ Wait Until Element Is Visible ${mp_close_drawer_button}
+ Click ${mp_close_drawer_button}
+ Wait Until Element Is Visible ${mp_items_table}
+
+MP: click on create new entity button:
+ [Arguments] ${buttonName}
+ Wait Until Element Is Visible xpath=//spy-headline//*[contains(text(),'${buttonName}')]
+ Click xpath=//spy-headline//*[contains(text(),'${buttonName}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: select option in expanded dropdown:
+ [Arguments] ${optionName}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Dropdown is not loaded
+ END
+ Wait Until Element Is Visible xpath=//nz-option-container[contains(@class,'ant-select-dropdown')]//span[contains(text(),'${optionName}')]
+ Click xpath=//nz-option-container[contains(@class,'ant-select-dropdown')]//span[contains(text(),'${optionName}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Dropdown is not loaded
+ END
+ Sleep 0.5s
+
+MP: switch to the tab:
+ [Arguments] ${tabName}
+ Wait Until Element Is Visible xpath=//web-spy-tabs[@class='spy-tabs']//div[@role='tablist'][contains(@class,'ant-tabs')]//div[contains(text(),'${tabName}')]
+ Click xpath=//web-spy-tabs[@class='spy-tabs']//div[@role='tablist'][contains(@class,'ant-tabs')]//div[contains(text(),'${tabName}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Tab is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: remove notification wrapper
+ TRY
+ ${flash_massage_state}= Page Should Contain Element ${mp_notification_wrapper} message=Notification wrapper message is not shown timeout=50ms
+ Remove element from HTML with JavaScript //spy-notification-wrapper
+ # Remove element from HTML with JavaScript (//spy-notification-wrapper//div)[1]
+ EXCEPT
+ Log Flash message is not shown
+ END
+
+MP: go to URL:
+ [Arguments] ${url} ${expected_response_code}=${EMPTY}
+ ${url}= Get URL Without Starting Slash ${url}
+ Set Browser Timeout ${browser_timeout}
+ ${response_code}= Go To ${mp_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ Disable Automatic Screenshots on Failure
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ Restore Automatic Screenshots on Failure
+ IF ${is_5xx} or not ${no_exception}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ ${response_code}= Go To ${mp_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ IF ${is_5xx}
+ # final attempt
+ TRY
+ LocalStorage Clear
+ Reload
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ ${response_code}= Go To ${mp_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ IF ${is_5xx}
+ Take Screenshot EMBED fullPage=True
+ Fail '${response_code}' error occurred on go to '${mp_url}${url}'
+ END
+ END
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ Should Not Contain ${page_title} error msg='${response_code}' error occurred on go to '${mp_url}${url}'
+ END
+ IF '${expected_response_code}' != '${EMPTY}'
+ ${expected_response_code}= Convert To Integer ${expected_response_code}
+ Should Be Equal ${response_code} ${expected_response_code} msg=Expected response code (${expected_response_code}) is not equal to the actual response code (${response_code}) on Go to: ${mp_url}${url}
+ END
+ RETURN ${response_code}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/common/common_ui.robot b/atest/testdata/performance/resources/common/common_ui.robot
new file mode 100644
index 0000000..5432fc5
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common_ui.robot
@@ -0,0 +1,632 @@
+*** Settings ***
+Library Browser run_on_failure=Take Screenshot \ EMBED \ fullPage=True
+Resource common.robot
+Resource ../pages/yves/yves_header_section.robot
+Resource ../pages/yves/yves_login_page.robot
+Resource ../pages/yves/yves_catalog_page.robot
+Resource common_api.robot
+
+*** Variables ***
+# *** UI SUITE VARIABLES ***
+${env} ui_suite
+${headless} true
+${browser} chromium
+${browser_timeout} 60 seconds
+${email_domain} @spryker.com
+${default_password} change123
+${default_secure_password} qweRTY_123456
+${admin_email} admin@spryker.com
+${device}
+# ${device} Desktop Chrome
+
+# *** PYZ VARIABLES ***
+${yves_env}
+${yves_at_env}
+${zed_env}
+${mp_env}
+${mp_root_env}
+${glue_env}
+
+*** Keywords ***
+Overwrite pyz variables
+ IF '${yves_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${yves_url} ${yves_dms_url}
+ ELSE
+ Set Suite Variable ${yves_url} ${yves_url}
+ END
+ ELSE
+ Set Suite Variable ${yves_url} ${yves_env}
+ END
+ IF '${yves_at_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${yves_at_url} ${yves_at_dms_url}
+ ELSE
+ Set Suite Variable ${yves_at_url} ${yves_at_url}
+ END
+ ELSE
+ Set Suite Variable ${yves_at_url} ${yves_at_env}
+ END
+ IF '${zed_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${zed_url} ${zed_dms_url}
+ ELSE
+ Set Suite Variable ${zed_url} ${zed_url}
+ END
+ ELSE
+ Set Suite Variable ${zed_url} ${zed_env}
+ END
+ IF '${mp_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${mp_url} ${mp_dms_url}
+ ELSE
+ Set Suite Variable ${mp_url} ${mp_url}
+ END
+ ELSE
+ Set Suite Variable ${mp_url} ${mp_env}
+ END
+ IF '${mp_root_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${mp_root_url} ${mp_root_dms_url}
+ ELSE
+ Set Suite Variable ${mp_root_url} ${mp_root_url}
+ END
+ ELSE
+ Set Suite Variable ${mp_root_url} ${mp_root_env}
+ END
+ IF '${glue_env}' == '${EMPTY}'
+ IF ${dms}
+ Set Suite Variable ${glue_url} ${glue_dms_url}
+ ELSE
+ Set Suite Variable ${glue_url} ${glue_url}
+ END
+ ELSE
+ Set Suite Variable ${glue_url} ${glue_env}
+ END
+ &{urls}= Create Dictionary yves_url ${yves_url} yves_at_url ${yves_at_url} zed_url ${zed_url} mp_url ${mp_url} glue_url ${glue_url}
+ FOR ${key} ${url} IN &{urls}
+ ${url_last_character}= Get Regexp Matches ${url} .$ flags=IGNORECASE
+ ${url_last_character}= Convert To String ${url_last_character}
+ ${url_last_character}= Replace String ${url_last_character} ' ${EMPTY}
+ ${url_last_character}= Replace String ${url_last_character} [ ${EMPTY}
+ ${url_last_character}= Replace String ${url_last_character} ] ${EMPTY}
+ IF '${url_last_character}' != '/' and '${key}' != 'glue_url'
+ ${url}= Set Variable ${url}${/}
+ END
+ ${var_url}= Set Variable ${url}
+ Set Suite Variable ${${key}} ${var_url}
+ END
+
+Create default Main Context
+ Log ${device}
+ IF '${device}' == '${EMPTY}'
+ ${main_context}= New Context viewport={'width': 1440, 'height': 1080} acceptDownloads=True
+ ELSE
+ ${device}= Get Device ${device}
+ ${main_context}= New Context &{device}
+ END
+ Set Suite Variable ${main_context}
+
+UI_suite_setup
+ Common_suite_setup
+ Overwrite pyz variables
+ IF ${verify_ssl}
+ New Browser ${browser} headless=${headless}
+ ELSE
+ New Browser ${browser} headless=${headless} args=['--ignore-certificate-errors']
+ END
+ Set Browser Timeout ${browser_timeout}
+ Create default Main Context
+ New Page ${yves_url}
+ Register Keyword To Run On Failure Take Screenshot EMBED fullPage=True
+
+UI_suite_teardown
+ Close Browser ALL
+
+UI_test_setup
+ Should Test Run
+ Register Keyword To Run On Failure Take Screenshot EMBED fullPage=True
+ Delete All Cookies
+ Set Browser Timeout ${browser_timeout}
+ Go To ${yves_url}
+
+UI_test_teardown
+ # Run Keyword If Test Failed Pause Execution
+ Delete All Cookies
+ Set Browser Timeout ${browser_timeout}
+ Register Keyword To Run On Failure Take Screenshot EMBED fullPage=True
+
+Select Random Option From List
+ [Arguments] ${dropDownLocator} ${dropDownOptionsLocator}
+ ${getOptionsCount}= Get Element Count ${dropDownOptionsLocator}
+ ${index}= Evaluate random.randint(0, ${getOptionsCount}-1) random
+ ${index}= Convert To String ${index}
+ Select From List By Index ${dropDownLocator} ${index}
+
+Click Element by xpath with JavaScript
+ [Arguments] ${xpath}
+ Evaluate Javascript ${None} document.evaluate("${xpath}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click()
+
+Click Element with JavaScript:
+ [Documentation] This keyword force clicks on web element using native JavaScript inside the browser. *Note*: it doesn't automatically wait until action is finished.
+ ...
+ ... *Examples:*
+ ...
+ ... `Click Element with JavaScript id=w3loginbtn`
+ ...
+ ... `Click Element with JavaScript xpath=//a[@id='w3loginbtn']`
+ ...
+ ... `Click Element with JavaScript css=#w3loginbtn`
+ ...
+ ... `Click Element with JavaScript name=w3loginname`
+ ...
+ [Arguments] ${locator}
+ ${element}= Get Element ${locator}
+ Evaluate JavaScript ${element} (e) => e.click({force:true})
+
+Click Element by id with JavaScript
+ [Arguments] ${id}
+ Evaluate Javascript ${None} document.getElementById("${id}").click()
+
+Remove element from HTML with JavaScript
+ [Arguments] ${xpath}
+ Evaluate Javascript ${None} var element=document.evaluate("${xpath}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;element.parentNode.removeChild(element);
+
+Add/Edit element attribute with JavaScript:
+ [Arguments] ${xpath} ${attribute} ${attributeValue}
+ Evaluate Javascript ${None} (document.evaluate("${xpath}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue).setAttribute("${attribute}", "${attributeValue}");
+
+Remove element attribute with JavaScript:
+ [Arguments] ${xpath} ${attribute}
+ Evaluate Javascript ${None} var element=document.evaluate("${xpath}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;element.removeAttribute("${attribute}"");
+
+### Helper keywords for migration from Selenium Library to Browser Library ###
+Wait Until Element Is Visible
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} visible ${timeout} ${message}
+
+Wait Until Page Contains Element
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} attached ${timeout} ${message}
+
+Wait Until Page Does Not Contain Element
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} detached ${timeout} ${message}
+
+Wait Until Element Is Enabled
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} enabled ${timeout} ${message}
+
+Wait Until Element Is Disabled
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} disabled ${timeout} ${message}
+
+Element Should Be Visible
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=0:00:05
+ Wait For Elements State ${locator} visible ${timeout} ${message}
+
+Page Should Contain Element
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=0:00:05
+ Wait For Elements State ${locator} attached ${timeout} ${message}
+
+Get Location
+ ${current_location}= Get URL
+ ${location}= Set Variable ${current_location}
+ Set Test Variable ${location} ${location}
+ RETURN ${location}
+
+Save current URL
+ ${current_url}= Get URL
+ ${url}= Set Variable ${current_url}
+ Set Test Variable ${url} ${url}
+ RETURN ${url}
+
+Wait Until Element Is Not Visible
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=${browser_timeout}
+ Wait For Elements State ${locator} hidden ${timeout} ${message}
+
+Page Should Contain Link
+ [Arguments] ${url} ${message}=${EMPTY}
+ ${hrefs}= Evaluate Javascript ${None} Array.from(document.querySelectorAll('a')).map(e => e.getAttribute('href'))
+ Should Contain ${hrefs} ${url}
+
+Scroll Element Into View
+ [Arguments] ${locator}
+ Hover ${locator}
+
+Input Text
+ [Arguments] ${locator} ${text}
+ Type Text ${locator} ${text} delay=10ms
+
+Table Should Contain
+ [Arguments] ${locator} ${expected} ${message}=${EMPTY} ${ignore_case}=${EMPTY}
+ Get Text ${locator} contains ${expected} ${message}
+
+Table Should Not Contain
+ [Arguments] ${locator} ${expected} ${message}=${EMPTY} ${ignore_case}=${EMPTY}
+ Get Text ${locator} not contains ${expected} ${message}
+
+Element Should Contain
+ [Arguments] ${locator} ${expected} ${message}=${EMPTY} ${ignore_case}=${EMPTY} ${timeout}=${browser_timeout}
+ Set Browser Timeout ${timeout}
+ Get Text ${locator} contains ${expected} ${message}
+ Set Browser Timeout ${browser_timeout}
+
+Element Text Should Be
+ [Arguments] ${locator} ${expected} ${message}=${EMPTY} ${ignore_case}=${EMPTY}
+ Get Text ${locator} equal ${expected} ${message}
+
+Wait Until Element Contains
+ [Arguments] ${locator} ${text} ${timeout}=${browser_timeout} ${message}=${EMPTY}
+ Get Text ${locator} contains ${text} ${message}
+
+Page Should Not Contain Element
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=0:00:05
+ Wait For Elements State ${locator} detached ${timeout} ${message}
+
+Element Should Not Contain
+ [Arguments] ${locator} ${text}
+ Get Text ${locator} validate "${text}" not in value
+
+Checkbox Should Be Selected
+ [Arguments] ${locator}
+ Get Checkbox State ${locator} == checked
+
+Checkbox Should Not Be Selected
+ [Arguments] ${locator}
+ Get Checkbox State ${locator} == unchecked
+
+Mouse Over
+ [Arguments] ${locator}
+ Hover ${locator}
+
+Element Should Not Be Visible
+ [Arguments] ${locator} ${message}=${EMPTY} ${timeout}=0:00:05
+ Wait For Elements State ${locator} hidden ${timeout} ${message}
+
+Get Element Attribute
+ [Arguments] ${locator} ${attribute}
+ ${element_attribute}= Get Attribute ${locator} ${attribute}
+ RETURN ${element_attribute}
+
+Select From List By Label
+ [Arguments] ${locator} ${value}
+ Select Options By ${locator} label ${value}
+
+Select From List By Value
+ [Arguments] ${locator} ${value}
+ Select Options By ${locator} value ${value}
+
+Select From List By Index
+ [Arguments] ${locator} ${value}
+ Select Options By ${locator} index ${value}
+
+Select From List By Text
+ [Arguments] ${locator} ${value}
+ Select Options By ${locator} text ${value}
+
+Select From List By Value Contains
+ [Arguments] ${selector} ${substring}
+ ${options}= Get Select Options ${selector}
+ ${matching_values}= Evaluate [option["value"] for option in ${options} if "${substring}" in option["value"]]
+ IF ${matching_values}
+ Select Options By ${selector} value ${matching_values}[0]
+ ELSE
+ Fail No option with substring '${substring}' found in ${selector}
+ END
+
+Select From List By Label Contains
+ [Arguments] ${selector} ${substring}
+ ${options}= Get Select Options ${selector}
+ ${matching_values}= Evaluate [option["label"] for option in ${options} if "${substring}" in option["label"]]
+ IF ${matching_values}
+ Select Options By ${selector} label ${matching_values}[0]
+ ELSE
+ Fail No option with substring '${substring}' found in ${selector}
+ END
+
+Create New Context
+ ${new_context}= New Context
+ New Page ${yves_url}
+
+Close Current Context
+ ${context_ids}= Get Context Ids
+ ${count_context_ids}= Get Length ${context_ids}
+ IF ${count_context_ids}>1 Close Context CURRENT
+
+Switch back to the Main Context
+ Switch Context ${main_context}
+
+Verify the src attribute of the image is accessible:
+ [Arguments] @{image_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${image_list_count}= get length ${image_list}
+ FOR ${index} IN RANGE 0 ${image_list_count}
+ ${image_to_check}= Get From List ${image_list} ${index}
+ ${image_src}= Get Element Attribute ${image_to_check} src
+ ${response}= GET ${image_src}
+ Should Be Equal '${response.status_code}' '200'
+ END
+
+Try reloading page until element is/not appear:
+ [Documentation] will reload the page until an element is shown or disappears. The second argument is the expected condition (true[shown]/false[disappeared]) for the element.
+ [Arguments] ${element} ${shouldBeDisplayed} ${tries}=20 ${timeout}=1s ${message}=Timeout exceeded, element state doesn't match the expected. Check screenshot in logs
+ ${shouldBeDisplayed}= Convert To Lower Case ${shouldBeDisplayed}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ FOR ${index} IN RANGE 0 ${tries}
+ IF (${index} == 5 or ${index} == 10 or ${index} == 15) and $element == $catalog_product_card_locator
+ Trigger multistore p&s
+ END
+ Disable Automatic Screenshots on Failure
+ ${elementAppears}= Run Keyword And Return Status Page Should Contain Element ${element}
+ Restore Automatic Screenshots on Failure
+ IF '${shouldBeDisplayed}'=='true' and '${elementAppears}'=='False'
+ Sleep ${timeout}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE IF '${shouldBeDisplayed}'=='false' and '${elementAppears}'=='True'
+ Sleep ${timeout}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE
+ Exit For Loop
+ END
+ END
+ IF ('${shouldBeDisplayed}'=='true' and '${elementAppears}'=='False') or ('${shouldBeDisplayed}'=='false' and '${elementAppears}'=='True')
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Take Screenshot EMBED fullPage=True
+ Fail ${message}
+ END
+
+Try reloading page until element does/not contain text:
+ [Documentation] will reload the page until an element text will be updated. The second argument is the expected condition (true[contains]/false[doesn't contain]) for the element text.
+ [Arguments] ${element} ${expectedText} ${shouldContain} ${tries}=20 ${timeout}=1s
+ ${shouldContain}= Convert To Lower Case ${shouldContain}
+ FOR ${index} IN RANGE 0 ${tries}
+ Disable Automatic Screenshots on Failure
+ ${textAppears}= Run Keyword And Return Status Element Text Should Be ${element} ${expectedText} timeout=${timeout}
+ Restore Automatic Screenshots on Failure
+ IF '${shouldContain}'=='true' and '${textAppears}'=='False'
+ Run Keywords Sleep ${timeout} AND Reload
+ ELSE IF '${shouldContain}'=='false' and '${textAppears}'=='True'
+ Run Keywords Sleep ${timeout} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ END
+ IF ('${shouldContain}'=='true' and '${textAppears}'=='False') or ('${shouldContain}'=='false' and '${textAppears}'=='True')
+ Take Screenshot EMBED fullPage=True
+ Fail 'Timeout exceeded, element text doesn't match the expected'
+ END
+
+Type Text When Element Is Visible
+ [Arguments] ${selector} ${text}
+ Wait Until Element Is Visible ${selector}
+ Type Text ${selector} ${text}
+
+Select From List By Value When Element Is Visible
+ [Arguments] ${selector} ${value}
+ Wait Until Element Is Visible ${selector}
+ Select From List By Value ${selector} ${value}
+
+Ping and go to URL:
+ [Arguments] ${url} ${timeout}=${EMPTY}
+ ${accessible}= Run Keyword And Ignore Error Send GET request and return status code: ${url} ${timeout}
+ ${successful}= Run Keyword And Ignore Error Should Contain Any '${response.status_code}' '200' '201' '202' '301' '302'
+ IF 'PASS' in $accessible and 'PASS' in $successful
+ Go To ${url}
+ ELSE
+ Fail '${url}' URL is not accessible or throws an error
+ END
+
+Click and retry if 5xx occurred:
+ [Arguments] ${selector} ${timeout}=300ms
+ Disable Automatic Screenshots on Failure
+ ${current_url}= Get URL
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ VAR ${sweet_alert_js_error_popup} xpath=//*[contains(@class,'sweet-alert')]
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${page_has_title}= Run Keyword And Return Status Should Not Be Empty ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error} and not ${page_has_title} and not ${no_exception}
+ Take Screenshot EMBED fullPage=True
+ Log 'Error on page '${current_url}' Retrying ...' level=WARN
+ Go to ${current_url}
+ END
+ ${page_contains_target_element}= Run Keyword And Return Status Page Should Contain Element ${selector}
+ IF not ${page_contains_target_element}
+ Take Screenshot EMBED fullPage=True
+ Log 'Expected element '${selector}' is not present on the page' level=WARN
+ RETURN
+ END
+ TRY
+ ${promise}= Promise To Wait For Response matcher=** timeout=${timeout}
+ Click ${selector}
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ EXCEPT
+ Log No requests were fired
+ END
+ IF '${result}[0]'=='FAIL'
+ VAR ${is_5xx} ${False}
+ ELSE
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ ${is_5xx}= Evaluate ${status} >= 500
+ IF ${is_5xx} Take Screenshot EMBED fullPage=True
+ END
+ ${statuses}= Create List
+ Set Browser Timeout ${timeout}
+ FOR ${i} IN RANGE 10
+ ${result}= Run Keyword And Ignore Error Wait For Response matcher=** timeout=${timeout}
+ IF '${result}[0]'=='FAIL'
+ Exit For Loop
+ END
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ Append To List ${statuses} ${status}
+ END
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ${is_5xx_in_page_load}= Evaluate any(status >= 500 for status in ${statuses})
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ ${page_has_title}= Run Keyword And Return Status Should Not Be Empty ${page_title}
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${is_5xx} and not ${is_5xx_in_page_load} and ${no_exception} and ${no_js_error} and ${page_has_title}
+ Restore Automatic Screenshots on Failure
+ RETURN
+ END
+ # Retry click if 5xx occurred or exception
+ Log message=Clicking '${selector}' triggered a 5xx error. Retrying ... level=WARN
+ Log ${is_5xx}
+ Log ${is_5xx_in_page_load}
+ Log ${no_exception}
+ Log ${no_js_error}
+ Log ${page_has_title}
+ Go to ${current_url}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ${page_contains_target_element}= Run Keyword And Return Status Page Should Contain Element ${selector} timeout=10ms
+ IF not ${page_contains_target_element}
+ Take Screenshot EMBED fullPage=True
+ Log 'Expected element '${selector}' is not present on the page on retry attempt, might be already processed' level=WARN
+ Restore Automatic Screenshots on Failure
+ RETURN
+ END
+ Restore Automatic Screenshots on Failure
+ Click With Options ${selector} force=True
+ ${statuses_retry}= Create List
+ Set Browser Timeout ${timeout}
+ Disable Automatic Screenshots on Failure
+ FOR ${i} IN RANGE 10
+ ${result}= Run Keyword And Ignore Error Wait For Response matcher=** timeout=100ms
+ IF '${result}[0]'=='FAIL'
+ Exit For Loop
+ END
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ Append To List ${statuses_retry} ${status}
+ END
+ Set Browser Timeout ${browser_timeout}
+ ${second_5xx_error_in_page_load}= Evaluate any(status >= 500 for status in ${statuses_retry})
+ Should Not Be True ${second_5xx_error_in_page_load} msg=Clicking '${selector}' triggered a 5xx error.
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ ${page_has_title}= Run Keyword And Return Status Should Not Be Empty ${page_title}
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ Restore Automatic Screenshots on Failure
+ Should Not Contain ${page_title} error msg=Clicking '${selector}' triggered a 5xx error.
+ IF not ${no_js_error} and not ${page_has_title} and not ${no_exception}
+ Take Screenshot EMBED fullPage=True
+ Fail Clicking '${selector}' triggered a 5xx error.
+ END
+
+Click and return True if 5xx occurred:
+ [Arguments] ${locator} ${timeout}=300ms
+ Disable Automatic Screenshots on Failure
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Restore Automatic Screenshots on Failure
+ Log page is not fully loaded
+ END
+ VAR ${sweet_alert_js_error_popup} xpath=//*[contains(@class,'sweet-alert')]
+ TRY
+ Disable Automatic Screenshots on Failure
+ ${promise}= Promise To Wait For Response matcher=** timeout=${timeout}
+ Click ${locator}
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ Restore Automatic Screenshots on Failure
+ EXCEPT
+ Restore Automatic Screenshots on Failure
+ Log No requests were fired
+ END
+ IF '${result}[0]'=='FAIL'
+ VAR ${is_5xx} ${False}
+ ELSE
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ ${is_5xx}= Evaluate ${status} >= 500
+ IF ${is_5xx} Take Screenshot EMBED fullPage=True
+ END
+ ${page_load_statuses}= Create List
+ Disable Automatic Screenshots on Failure
+ FOR ${i} IN RANGE 10
+ ${result}= Run Keyword And Ignore Error Wait For Response matcher=** timeout=${timeout}
+ IF '${result}[0]'=='FAIL'
+ Exit For Loop
+ END
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ Append To List ${page_load_statuses} ${status}
+ END
+ ${is_5xx_in_page_load}= Evaluate any(status >= 500 for status in ${page_load_statuses})
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ Restore Automatic Screenshots on Failure
+ IF ${is_5xx} or ${is_5xx_in_page_load} or not ${no_exception} or not ${no_js_error}
+ RETURN ${True}
+ ELSE
+ RETURN ${False}
+ END
+
+Disable Automatic Screenshots on Failure
+ # Save the current run-on-failure handler and disable it
+ ${prev}= Register Keyword To Run On Failure None
+ VAR ${PREV_RUN_ON_FAILURE} ${prev} scope=SUITE
+
+Restore Automatic Screenshots on Failure
+ # Restore the saved run-on-failure handler
+ Register Keyword To Run On Failure Take Screenshot EMBED fullPage=True
+
+# *** Example of intercepting the network request ***
+# [Arguments] ${eventName} ${timeout}=30s
+# ${response}= Wait for response matcher=bazaarvoice\\.com\\/\\w+\\.gif\\?.*type=${eventName} timeout=${timeout}
+# Should be true ${response}[ok]
+# ** OR **
+# [Arguments] ${timeout}=30s
+# ${response}= Wait for response matcher=usercentrics.*?graphql timeout=${timeout}
+# Should be true ${response}[ok]
+
diff --git a/atest/testdata/performance/resources/common/common_yves.robot b/atest/testdata/performance/resources/common/common_yves.robot
new file mode 100644
index 0000000..1686064
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common_yves.robot
@@ -0,0 +1,842 @@
+*** Settings ***
+Resource common_ui.robot
+Resource ../pages/yves/yves_overview_page.robot
+Resource ../pages/yves/yves_profile_page.robot
+Resource ../pages/yves/yves_overview_page.robot
+Resource ../pages/yves/yves_profile_page.robot
+Resource ../pages/yves/yves_catalog_page.robot
+Resource ../pages/yves/yves_product_details_page.robot
+Resource ../pages/yves/yves_company_users_page.robot
+Resource ../pages/yves/yves_shopping_lists_page.robot
+Resource ../pages/yves/yves_shopping_carts_page.robot
+Resource ../pages/yves/yves_shopping_cart_page.robot
+Resource ../pages/yves/yves_shopping_list_page.robot
+Resource ../pages/yves/yves_checkout_success_page.robot
+Resource ../pages/yves/yves_address_page.robot
+Resource ../pages/yves/yves_address_page.robot
+Resource ../pages/yves/yves_order_history_page.robot
+Resource ../pages/yves/yves_returns_page.robot
+Resource ../pages/yves/yves_newsletter_page.robot
+Resource ../pages/yves/yves_returns_page.robot
+Resource ../pages/yves/yves_newsletter_page.robot
+Resource ../pages/yves/yves_order_details_page.robot
+Resource ../pages/yves/yves_customer_account_page.robot
+Resource ../pages/yves/yves_quote_requests_page.robot
+Resource ../pages/yves/yves_quote_request_page.robot
+Resource ../pages/yves/yves_choose_bundle_to_configure_page.robot
+Resource ../pages/yves/yves_create_return_page.robot
+Resource ../pages/yves/yves_return_details_page.robot
+Resource ../pages/yves/yves_checkout_summary_page.robot
+Resource ../pages/yves/yves_checkout_cancel_payment_page.robot
+Resource ../steps/header_steps.robot
+Resource ../steps/checkout_steps.robot
+
+*** Variables ***
+${notification_area} xpath=//section[@data-qa='component notification-area']
+${footer_section}= xpath=//*[@class='footer']
+
+*** Keywords ***
+Yves: login on Yves with provided credentials:
+ [Arguments] ${email} ${password}=${default_password} ${agent_assist}=${False}
+ Set Browser Timeout ${browser_timeout}
+ ${currentURL}= Get Url
+ IF '/login' not in '${currentURL}'
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ IF 'agent' in '${currentURL}' or ${agent_assist}
+ Yves: go to URL: /agent/login
+ ELSE
+ Yves: go to URL: /login
+ END
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${is_login_page}= Run Keyword And Ignore Error Page Should Contain Element locator=${email_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_login_page
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ IF 'agent' in '${currentURL}' or ${agent_assist}
+ Yves: go to URL: /agent/login
+ ELSE
+ Yves: go to URL: /login
+ END
+ END
+ ${currentURL}= Get Url
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Type Text ${email_field} ${email}
+ Type Text ${password_field} ${password}
+ Click ${form_login_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ # workaround for the issue with deadlocks on concurrent login attempts
+ TRY
+ IF 'agent' in '${currentURL}'
+ Page Should Contain Element ${customerSearchWidget} Login Failed! timeout=1s
+ ELSE
+ Page Should Contain Element ${user_header_logout_button} Login Failed! timeout=1s
+ END
+ EXCEPT
+ Reload
+ IF 'agent' in '${currentURL}'
+ Page Should Contain Element locator=${customerSearchWidget} message=Yves: Login Failed timeout=5s
+ ELSE
+ Page Should Contain Element locator=${user_header_logout_button} message=Yves: Login Failed timeout=5s
+ END
+ END
+ Yves: remove flash messages
+
+Yves: login on Yves with provided credentials and expect error:
+ [Arguments] ${email} ${password}=${default_password}
+ Set Browser Timeout ${browser_timeout}
+ ${currentURL}= Get Url
+ IF '/login' not in '${currentURL}'
+ Delete All Cookies
+ Reload
+ Yves: go to URL: /login
+ END
+ Disable Automatic Screenshots on Failure
+ ${is_login_page}= Run Keyword And Ignore Error Page Should Contain Element locator=${email_field} message=Login page is not displayed timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_login_page
+ Delete All Cookies
+ Yves: go to the 'Home' page
+ Yves: go to URL: /login
+ END
+ Type Text ${email_field} ${email}
+ Type Text ${password_field} ${password}
+ Click ${form_login_button}
+
+ Page Should Not Contain Element ${user_header_logout_button} message=Yves: logged in successfully but should not be
+
+ Yves: flash message should be shown: error Please check that your E-mail address and password are correct and that you have confirmed your E-mail address by clicking the link in the registration message
+ Yves: remove flash messages
+
+Yves: go to PDP of the product with sku:
+ [Arguments] ${sku} ${wait_for_p&s}=${False} ${iterations}=26 ${delay}=5s
+ Yves: go to URL: /search?q=${sku}
+ ### *** promise for P&S *** ####
+ ${wait_for_p&s}= Convert To String ${wait_for_p&s}
+ ${wait_for_p&s}= Convert To Lower Case ${wait_for_p&s}
+ IF '${wait_for_p&s}' == 'true'
+ ${wait_for_p&s}= Set Variable ${True}
+ END
+ IF '${wait_for_p&s}' == 'false'
+ ${wait_for_p&s}= Set Variable ${False}
+ END
+ IF ${wait_for_p&s}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${result}= Run Keyword And Ignore Error Page Should Contain Element ${catalog_product_card_locator} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Product '${sku}' is not displayed in the search results or its PDP is not accessible
+ END
+ IF ${index} == 5 or ${index} == 10 or ${index} == 15
+ Trigger multistore p&s
+ END
+ IF 'FAIL' in ${result}
+ Sleep ${delay}
+ Yves: go to URL: /search?q=${sku}
+ Continue For Loop
+ ELSE
+ ${pdp_url}= Get Element Attribute ${catalog_product_card_locator} href
+ ${currentURL}= Get Location
+ ${has_at_cur}= Run Keyword And Return Status Should Match Regexp ${currentURL} (?i)(?:\\.at\\.|/at/)
+ ${has_at_pdp}= Run Keyword And Return Status Should Match Regexp ${pdp_url} (?i)(?:\\.at\\.|/at/)
+
+ # Remove `.at.` in host and `/at/` path segment (case-insensitive)
+ IF ${has_at_cur} or ${has_at_pdp}
+ TRY
+ ${pdp_url}= Replace String Using Regexp ${pdp_url} (?i)/at/ /
+ EXCEPT
+ Log No /at/ in URL
+ END
+ END
+
+ Yves: go to URL: ${pdp_url}?fake=${random}+${index}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${pdp_available}= Run Keyword And Ignore Error Wait Until Page Contains Element ${pdp_main_container_locator}[${env}] timeout=0.5s
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $pdp_available
+ Exit For Loop
+ ELSE
+ Sleep ${delay}
+ Yves: go to URL: /search?q=${sku}
+ Continue For Loop
+ END
+ END
+ END
+ ELSE
+ TRY
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ Wait Until Page Contains Element ${catalog_product_card_locator}
+ Click ${catalog_product_card_locator}
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ EXCEPT
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to URL: /search?q=${sku}
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ Wait Until Page Contains Element ${catalog_product_card_locator}
+ ${pdp_url}= Get Element Attribute ${catalog_product_card_locator} href
+ ${currentURL}= Get Location
+
+ ${has_at_cur}= Run Keyword And Return Status Should Match Regexp ${currentURL} (?i)(?:\\.at\\.|/at/)
+ ${has_at_pdp}= Run Keyword And Return Status Should Match Regexp ${pdp_url} (?i)(?:\\.at\\.|/at/)
+
+ IF ${has_at_cur} or ${has_at_pdp}
+ TRY
+ ${pdp_url}= Replace String Using Regexp ${pdp_url} (?i)/at/ /
+ EXCEPT
+ Log No /at/ in URL
+ END
+ END
+ Yves: go to URL: ${pdp_url}?fake=${random}+${random}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+ END
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: '${pageName}' page is displayed
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${pageName}' == 'Company Users' Page Should Contain Element ${company_users_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Login' Page Should Contain Element ${login_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Overview' Page Should Contain Element ${overview_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Profile' Page Should Contain Element ${profile_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Shopping Lists' Page Should Contain Element ${shopping_lists_page_form_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Shopping List' Page Should Contain Element ${shopping_list_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Shopping Cart' Page Should Contain Element ${shopping_cart_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Shopping Carts' Page Should Contain Element ${shopping_carts_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Quick Order' Page Should Contain Element ${quick_order_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Thank you' Page Should Contain Element ${success_page_main_container_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Addresses' Page Should Contain Element ${address_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Order History' Page Should Contain Element ${order_history_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Returns' Page Should Contain Element ${returns_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Newsletter' Page Should Contain Element ${newsletter_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Order Details' Page Should Contain Element ${order_details_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Select Business Unit' Page Should Contain Element ${customer_account_business_unit_selector} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Summary' Page Should Contain Element ${checkout_summary_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Quote Requests' Page Should Contain Element ${quote_requests_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Quote Request Details' Page Should Contain Element ${quote_request_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Choose Bundle to configure' Page Should Contain Element ${choose_bundle_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Create Return' Page Should Contain Element ${create_return_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Return Details' Page Should Contain Element ${return_details_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Payment cancellation' Page Should Contain Element ${cancel_payment_page_main_container_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Merchant Profile' Page Should Contain Element ${merchant_profile_main_content_locator} ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE IF '${pageName}' == 'Wishlist' Page Should Contain Element ${wishlist_main_content_locator}[${env}] ${pageName} page is not displayed ${browser_timeout}
+ ... ELSE Fail '${pageName}' page is not displayed or the page name is incorrect
+
+Yves: remove flash messages
+ TRY
+ ${flash_massage_state}= Page Should Contain Element ${notification_area} message=Flash message is not shown timeout=500ms
+ Remove element from HTML with JavaScript //section[@data-qa='component notification-area']
+ EXCEPT
+ Log Flash message is not shown
+ END
+
+Yves: flash message '${condition}' be shown
+ IF '${condition}' == 'should'
+ Wait Until Element Is Visible ${notification_area}
+ ELSE
+ Page Should Not Contain Element ${notification_area}
+ END
+
+Yves: flash message should be shown:
+ [Documentation] ${type} can be: error, success
+ [Arguments] ${type} ${text} ${timeout}=${browser_timeout}
+ IF '${type}' == 'error'
+ Element Should Be Visible locator=xpath=//flash-message[contains(@class,'alert')]//div[contains(text(),'${text}')] timeout=${timeout}
+ ELSE
+ IF '${type}' == 'success' Element Should Be Visible locator=xpath=//flash-message[contains(@class,'success')]//div[contains(text(),'${text}')] timeout=${timeout}
+ END
+
+Yves: logout on Yves as a customer
+ Delete All Cookies
+ Reload
+
+Yves: go to the 'Home' page
+ Set Browser Timeout ${browser_timeout}
+ ${currentURL}= Get Location
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}
+ ELSE
+ Go To ${yves_url}
+ END
+
+Yves: go to AT store 'Home' page if other store not specified:
+ [Arguments] ${store}=AT
+ Set Browser Timeout ${browser_timeout}
+ ${dms_state}= Convert To String ${dms}
+ IF '${dms_state}' != 'True'
+ Go To ${yves_at_url}
+ ELSE
+ Go To ${yves_url}
+ Wait Until Element Is Visible ${store_switcher_header_menu_item}
+ Select From List By Label Contains ${store_switcher_header_menu_item} ${store}
+ Wait Until Element Contains ${store_switcher_selected_option} ${store}
+ ${logoURL}= Get Element Attribute ${header_logo_link} href
+ Yves: go to URL: ${logoURL}
+ END
+
+Yves: wait until store switcher contains:
+ [Arguments] ${store} ${tries}=30 ${timeout}=3s ${message}='Timeout exceeded while waiting for '${store}' store in the store switcher. Check P&S'
+ Go To ${yves_url}
+ Wait Until Element Is Visible ${store_switcher_header_menu_item}
+ FOR ${index} IN RANGE 0 ${tries}
+ Disable Automatic Screenshots on Failure
+ ${storeAppears}= Run Keyword And Return Status Wait Until Element Contains locator=${store_switcher_header_menu_item} text=${store} timeout=${timeout}
+ Restore Automatic Screenshots on Failure
+ IF '${storeAppears}'=='False'
+ Run Keywords Sleep ${timeout} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ END
+ IF '${storeAppears}'=='False'
+ Take Screenshot EMBED fullPage=True
+ Fail ${message}
+ END
+
+Yves: select currency Euro if other currency not specified
+ [Arguments] ${currency_name}=Euro ${currency_code}=EUR
+ Set Browser Timeout ${browser_timeout}
+ ${dms_state}= Convert To String ${dms}
+ IF '${dms_state}' != 'True'
+ Go To ${yves_at_url}
+ ELSE
+ Go To ${yves_url}
+ Wait Until Element Is visible ${currency_switcher_header_menu_item}[${env}]
+ Select From List By Value ${currency_switcher_header_menu_item}[${env}] ${currency_code}
+ IF '${env}' in ['ui_suite']
+ Wait Until Element Contains //*[@data-qa='component header']//select[contains(@name,'currency')]/option[@selected=''] ${currency_name}
+ ELSE
+ Wait Until Element Contains //*[@data-qa='component header']//select[contains(@name,'currency')]/option[@selected=''] ${currency_code}
+ END
+ END
+
+Yves: get the last placed order ID by current customer
+ [Documentation] Returns orderID of the last order from customer account
+ Set Browser Timeout ${browser_timeout}
+ Yves: go to URL: /customer/order
+ ${lastPlacedOrder}= Get Text xpath=//div[contains(@data-qa,'component order-table')]//tr[1]//td[1]
+ Set Suite Variable ${lastPlacedOrder} ${lastPlacedOrder}
+ RETURN ${lastPlacedOrder}
+
+Yves: go to URL:
+ [Arguments] ${url} ${expected_response_code}=${EMPTY}
+ ${url}= Get URL Without Starting Slash ${url}
+ Set Browser Timeout ${browser_timeout}
+ ${currentURL}= Get Location
+ IF '.at.' in '${currentURL}' or '/at/' in '${currentURL}' or '/AT/' in '${currentURL}'
+ ${response_code}= Go To ${yves_at_url}${url}
+ ELSE
+ ${response_code}= Go To ${yves_url}${url}
+ END
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ IF ${is_5xx} or not ${no_exception}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ IF '.at.' in '${currentURL}' or '/at/' in '${currentURL}' or '/AT/' in '${currentURL}'
+ ${response_code}= Go To ${yves_at_url}${url}
+ ELSE
+ ${response_code}= Go To ${yves_url}${url}
+ END
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ IF ${is_5xx}
+ IF '.at.' in '${currentURL}' or '/at/' in '${currentURL}' or '/AT/' in '${currentURL}'
+ Fail '${response_code}' error occurred on Go to: ${yves_at_url}${url}
+ ELSE
+ Fail '${response_code}' error occurred on Go to: ${yves_url}${url}
+ END
+ END
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ Should Not Contain ${page_title} error msg='${response_code}' error occurred on Go to: ${yves_url}${url}
+ END
+ IF '${expected_response_code}' != '${EMPTY}'
+ ${expected_response_code}= Convert To Integer ${expected_response_code}
+ Should Be Equal ${response_code} ${expected_response_code} msg=Expected response code (${expected_response_code}) is not equal to the actual response code (${response_code}) on Go to: ${url}
+ END
+ RETURN ${response_code}
+
+Yves: go to AT store URL if other store not specified:
+ [Arguments] ${url} ${store}=AT
+ Set Browser Timeout ${browser_timeout}
+ ${url}= Get URL Without Starting Slash ${url}
+ ${dms_state}= Convert To String ${dms}
+ IF '${dms_state}' != 'True'
+ Go To ${yves_at_url}${url}
+ ELSE
+ Go To ${yves_url}
+ Wait Until Element Is Visible ${store_switcher_header_menu_item}
+ Select From List By Label Contains ${store_switcher_header_menu_item} ${store}
+ Wait Until Element Contains ${store_switcher_selected_option} ${store}
+ Go To ${yves_url}${url}
+ END
+
+Yves: go to newly created page by URL:
+ [Arguments] ${url} ${delay}=5s ${iterations}=31
+ FOR ${index} IN RANGE 1 ${iterations}
+ Go To ${yves_url}${url}?${index}
+ Disable Automatic Screenshots on Failure
+ ${page_not_published}= Run Keyword And Return Status Page Should Contain Element xpath=//main//*[contains(text(),'ERROR 404')]
+ Restore Automatic Screenshots on Failure
+ IF '${page_not_published}'=='True'
+ Sleep ${delay}
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Newly created URL is not accessible (404 error), check P&S
+ END
+ END
+
+Yves: go to newly created page by URL on AT store if other store not specified:
+ [Arguments] ${url} ${delay}=5s ${iterations}=31 ${store}=AT
+ ${dms_state}= Convert To String ${dms}
+ Set Browser Timeout ${browser_timeout}
+ FOR ${index} IN RANGE 1 ${iterations}
+ IF '${dms_state}' != 'True'
+ Go To ${yves_at_url}${url}?${index}
+ ELSE
+ Go To ${yves_url}
+ Wait Until Element Is Visible ${store_switcher_header_menu_item}
+ Select From List By Label Contains ${store_switcher_header_menu_item} ${store}
+ Wait Until Element Contains ${store_switcher_selected_option} ${store}
+ ${logoURL}= Get Element Attribute ${header_logo_link} href
+ Yves: go to URL: ${logoURL}
+ Go To ${yves_url}${url}?${index}
+ END
+ Disable Automatic Screenshots on Failure
+ ${page_not_published}= Run Keyword And Return Status Page Should Contain Element xpath=//main//*[contains(text(),'ERROR 404')]
+ Restore Automatic Screenshots on Failure
+ IF '${page_not_published}'=='True'
+ Sleep ${delay}
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Newly created CMS page is not accessible (404 error), check P&S
+ END
+ END
+
+Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs:
+ [Arguments] ${url} ${delay}=5s ${iterations}=31 ${store}=AT
+ ${dms_state}= Convert To String ${dms}
+ Set Browser Timeout ${browser_timeout}
+ FOR ${index} IN RANGE 1 ${iterations}
+ IF '${dms_state}' != 'True'
+ Go To ${url}
+ ELSE
+ Go To ${yves_url}
+ Wait Until Element Is Visible ${store_switcher_header_menu_item}
+ Select From List By Label Contains ${store_switcher_header_menu_item} ${store}
+ Wait Until Element Contains ${store_switcher_selected_option} ${store}
+ ${logoURL}= Get Element Attribute ${header_logo_link} href
+ Yves: go to URL: ${logoURL}
+ Go To ${url}
+ END
+ Disable Automatic Screenshots on Failure
+ ${page_not_published}= Run Keyword And Return Status Page Should Contain Element xpath=//main//*[contains(text(),'ERROR 404')]
+ Restore Automatic Screenshots on Failure
+ IF '${page_not_published}'=='False'
+ Run Keyword Sleep ${delay}
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail URL is still accessible but should not, check P&S
+ END
+ END
+
+Yves: go to URL and refresh until 404 occurs:
+ [Arguments] ${url} ${delay}=5s ${iterations}=31
+ FOR ${index} IN RANGE 1 ${iterations}
+ Go To ${url}
+ Disable Automatic Screenshots on Failure
+ ${page_not_published}= Run Keyword And Return Status Page Should Contain Element xpath=//main//*[contains(text(),'ERROR 404')]
+ Restore Automatic Screenshots on Failure
+ IF '${page_not_published}'=='False'
+ Run Keyword Sleep ${delay}
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail URL is still accessible but should not, check P&S
+ END
+ END
+
+Yves: go to external URL:
+ [Arguments] ${url}
+ Set Browser Timeout ${browser_timeout}
+ Go To ${url}
+
+Yves: go to second navigation item level:
+ [Arguments] ${navigation_item_level1} ${navigation_item_level2}
+ ${nodeClass}= Get Element Attribute xpath=//div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li class
+ ${nodeClass}= Replace String ${nodeClass} \n ${EMPTY}
+ ${nodeShownClass}= Set Variable is-shown
+ ${nodeUpdatedClass}= Set Variable ${nodeClass} ${nodeShownClass}
+ ${1LevelXpath}= Set Variable //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li
+ Add/Edit element attribute with JavaScript: ${1LevelXpath} class ${nodeUpdatedClass}
+ Wait Until Element Is Visible //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'menu--lvl-1')]
+ Click Element by xpath with JavaScript //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'menu--lvl-1')]//li[contains(@class,'menu__item--lvl-1')]/span/*[contains(@class,'lvl-1')][1][text()='${navigation_item_level2}']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: go to first navigation item level:
+ [Arguments] ${navigation_item_level1}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Wait Until Element Is Visible xpath=//div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']
+ Click Element by xpath with JavaScript //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ELSE IF '${env}' in ['ui_suite']
+ Wait Until Element Is Visible xpath=(//header//nav[contains(@data-qa,'navigation-multilevel')]/ul/li[contains(.,'${navigation_item_level1}')])[1]
+ Click xpath=(//header//nav[contains(@data-qa,'navigation-multilevel')]/ul/li[contains(.,'${navigation_item_level1}')])[1]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ELSE
+ Wait Until Element Is Visible xpath=//*[contains(@class,'header') and @data-qa='component header']//*[contains(@data-qa,'navigation-multilevel')]/*[contains(@class,'navigation-multilevel-node__link--lvl-1') and contains(text(),'${navigation_item_level1}')]
+ Click Element by xpath with JavaScript //*[contains(@class,'header') and @data-qa='component header']//*[contains(@data-qa,'navigation-multilevel')]/*[contains(@class,'navigation-multilevel-node__link--lvl-1') and contains(text(),'${navigation_item_level1}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: go to third navigation item level:
+ [Arguments] ${navigation_item_level1} ${navigation_item_level3}
+ ${nodeClass}= Get Element Attribute xpath=//div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li class
+ ${nodeClass}= Replace String ${nodeClass} \n ${EMPTY}
+ ${nodeShownClass}= Set Variable is-shown
+ ${nodeUpdatedClass}= Set Variable ${nodeClass} ${nodeShownClass}
+ ${1LevelXpath}= Set Variable //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li
+ Add/Edit element attribute with JavaScript: ${1LevelXpath} class ${nodeUpdatedClass}
+ Wait Until Element Is Visible //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'menu--lvl-1')]
+ Click Element by xpath with JavaScript //div[@class='header__navigation']//navigation-multilevel[@data-qa='component navigation-multilevel']/ul[@class='menu menu--lvl-0']//li[contains(@class,'menu__item--lvl-0')]/span/*[contains(@class,'lvl-0')][1][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'menu--lvl-2')]//li[contains(@class,'menu__item--lvl-2')]/span/*[contains(@class,'lvl-2')][1][text()='${navigation_item_level3}']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: get index of the first available product
+ [Documentation] For B2B this keyword should be used only for logged in customers, otherwise add to cart buttons are absent and it returns wrong index
+ Yves: perform search by: ${EMPTY}
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ ${productsCount}= Get Element Count xpath=//product-item[@data-qa='component product-item']
+ FOR ${index} IN RANGE 1 ${productsCount}+1
+ Disable Automatic Screenshots on Failure
+ ${status}= IF '${env}'=='ui_b2b' Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled=''] timeout=10ms
+ ${status}= IF '${env}'=='ui_suite' Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled=''] timeout=10ms
+ ... ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c'] Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//ajax-add-to-cart//button Add to cart button is missing timeout=10ms
+ Restore Automatic Screenshots on Failure
+ ${pdp_url}= IF '${env}' in ['ui_b2b','ui_suite'] Get Element Attribute xpath=(//product-item[@data-qa='component product-item'])[${index}]//a[@itemprop='url'] href
+ IF 'PASS' in $status and '${env}' in ['ui_b2b','ui_suite'] Continue For Loop
+ IF 'bundle' in '${pdp_url}' and '${env}' in ['ui_b2b','ui_suite'] Continue For Loop
+ IF 'FAIL' in $status and '${env}' in ['ui_b2b','ui_suite']
+ Return From Keyword ${index}
+ Log ${index}
+ Exit For Loop
+ END
+ ${pdp_url}= IF '${env}' in ['ui_b2c','ui_mp_b2c'] Get Element Attribute xpath=(//product-item[@data-qa='component product-item'])[${index}]//div[contains(@class,'product-item__image')]//a[contains(@class,'link-detail-page')] href
+ IF 'FAIL' in $status and '${env}' in ['ui_b2c','ui_mp_b2c'] Continue For Loop
+ IF 'bundle' in '${pdp_url}' and '${env}' in ['ui_b2c','ui_mp_b2c'] Continue For Loop
+ IF 'PASS' in $status and '${env}' in ['ui_b2c','ui_mp_b2c']
+ Return From Keyword ${index}
+ Log ${index}
+ Exit For Loop
+ END
+ END
+ ${productIndex}= Set Variable ${index}
+ Return From Keyword ${productIndex}
+
+Yves: get index of the first available product on marketplace
+ Yves: perform search by: ${EMPTY}
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ ${currentURL}= Get Location
+ ${productsCount}= Get Element Count xpath=//product-item[@data-qa='component product-item']
+ FOR ${index} IN RANGE 1 ${productsCount}+1
+ Click xpath=(//product-item[@data-qa='component product-item'])[${index}]//a[contains(@class,'link-detail-page') and (contains(@class,'info')) or (contains(@class,'name'))]
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+ Disable Automatic Screenshots on Failure
+ ${status}= Run Keyword And Ignore Error Page should contain element ${pdp_add_to_cart_disabled_button}[${env}] timeout=10ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $status
+ Go to ${currentURL}
+ Continue For Loop
+ END
+ IF 'FAIL' in $status
+ Run Keywords
+ Return From Keyword ${index}
+ Log ${index}
+ Exit For Loop
+ END
+ END
+ ${productIndex}= Set Variable ${index}
+ Return From Keyword ${productIndex}
+
+Yves: go to the PDP of the first available product
+ IF '${env}' in ['ui_mp_b2b','ui_mp_b2c']
+ ${index}= Yves: get index of the first available product on marketplace
+ ELSE
+ ${index}= Yves: get index of the first available product
+ Click xpath=(//product-item[@data-qa='component product-item'])[${index}]//a[contains(@class,'link-detail-page') and (contains(@class,'info')) or (contains(@class,'name'))]
+ END
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+
+Yves: go to the PDP of the first product on open catalog page
+ Click xpath=(//product-item[@data-qa='component product-item'][1]//a[contains(@class,'link-detail-page') and (contains(@class,'info')) or (contains(@class,'name'))])[1]
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+
+Yves: go to the PDP of the first available product on current catalog page
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ IF '${env}' in ['ui_mp_b2b','ui_mp_b2c']
+ ${productsCount}= Get Element Count xpath=//product-item[@data-qa='component product-item']
+ ${currentURL}= Get Location
+ FOR ${index} IN RANGE 1 ${productsCount}+1
+ Click xpath=(//product-item[@data-qa='component product-item'])[${index}]//a[contains(@class,'link-detail-page') and (contains(@class,'info')) or (contains(@class,'name'))]
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+ Disable Automatic Screenshots on Failure
+ ${status}= Run Keyword And Ignore Error Page should contain element ${pdp_add_to_cart_disabled_button}[${env}] timeout=10ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $status
+ Go to ${currentURL}
+ Continue For Loop
+ END
+ IF 'FAIL' in $status
+ VAR ${index_of_first_available_product} ${index}
+ BREAK
+ END
+ END
+ ELSE
+ ${productsCount}= Get Element Count xpath=//product-item[@data-qa='component product-item']
+ FOR ${index} IN RANGE 1 ${productsCount}+1
+ Disable Automatic Screenshots on Failure
+ ${status}= IF '${env}'=='ui_b2b' Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled=''] timeout=10ms
+ ${status}= IF '${env}'=='ui_suite' Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled=''] timeout=10ms
+ ... ELSE IF '${env}' in ['ui_b2c'] Run Keyword And Ignore Error Page should contain element xpath=(//product-item[@data-qa='component product-item'])[${index}]//ajax-add-to-cart//button Add to cart button is missing timeout=10ms
+ ${pdp_url}= IF '${env}' in ['ui_b2b','ui_suite'] Get Element Attribute xpath=(//product-item[@data-qa='component product-item'])[${index}]//a[@itemprop='url'] href
+ IF 'PASS' in $status and '${env}' in ['ui_b2b','ui_suite'] Continue For Loop
+ IF 'bundle' in '${pdp_url}' and '${env}' in ['ui_b2b','ui_suite'] Continue For Loop
+ IF 'FAIL' in $status and '${env}' in ['ui_b2b','ui_suite']
+ VAR ${index_of_first_available_product} ${index}
+ BREAK
+ END
+ ${pdp_url}= IF '${env}' in ['ui_b2c'] Get Element Attribute xpath=(//product-item[@data-qa='component product-item'])[${index}]//div[contains(@class,'product-item__image')]//a[contains(@class,'link-detail-page')] href
+ IF 'FAIL' in $status and '${env}' in ['ui_b2c'] Continue For Loop
+ IF 'bundle' in '${pdp_url}' and '${env}' in ['ui_b2c'] Continue For Loop
+ IF 'PASS' in $status and '${env}' in ['ui_b2c']
+ VAR ${index_of_first_available_product} ${index}
+ BREAK
+ END
+ END
+ Restore Automatic Screenshots on Failure
+ Click xpath=(//product-item[@data-qa='component product-item'])[${index_of_first_available_product}]//a[contains(@class,'link-detail-page') and (contains(@class,'info')) or (contains(@class,'name'))]
+ Wait Until Page Contains Element ${pdp_main_container_locator}[${env}]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: check if cart is not empty and clear it
+ Yves: go to the 'Home' page
+ Yves: go to shopping cart page
+ ${productsInCart}= Get Element Count xpath=//main//form[contains(@name,'removeFromCartForm')]//button | //main//form[contains(@action,'bundle/async/remove')]//button
+ IF ${productsInCart} > 0 Helper: delete all items in cart
+
+Helper: delete all items in cart
+ ${productsInCart}= Get Element Count xpath=//main//form[contains(@name,'removeFromCartForm')]//button | //main//form[contains(@action,'bundle/async/remove')]//button
+ IF ${productsInCart} == 0 Log Shopping cart is empty
+ FOR ${index} IN RANGE 0 ${productsInCart}
+ Click xpath=(//main//form[contains(@name,'removeFromCartForm')]//button | //main//form[contains(@action,'bundle/async/remove')]//button)[1]
+ Yves: remove flash messages
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: try reloading page if element is/not appear:
+ [Arguments] ${element} ${isDisplayed} ${iterations}=26 ${sleep}=5s ${message}=expected element state is not reached after ${iterations} iterations. Locator: ${element}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ${isDisplayed}= Convert To Lower Case ${isDisplayed}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${elementAppears}= Run Keyword And Return Status Element Should Be Visible ${element}
+ Restore Automatic Screenshots on Failure
+ IF '${isDisplayed}'=='true' and '${elementAppears}'=='False'
+ Sleep ${sleep}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE IF '${isDisplayed}'=='false' and '${elementAppears}'=='True'
+ Sleep ${sleep}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE
+ Exit For Loop
+ END
+
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail ${message}
+ END
+ END
+
+Yves: get current lang
+ ${lang}= get attribute xpath=//html lang
+ return from keyword ${lang}
+
+Yves: page should contain script with attribute:
+ [Arguments] ${attribute} ${value}
+ Try reloading page until element is/not appear: xpath=//head//script[@${attribute}='${value}'] true
+ Page Should Contain Element xpath=//head//script[@${attribute}='${value}']
+
+Yves: page should contain script with id:
+ [Arguments] ${scriptId}
+ Yves: page should contain script with attribute: id ${scriptId}
+
+Yves: validate the page title:
+ [Arguments] ${title}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Yves: try reloading page if element is/not appear: element=xpath=//h3[contains(text(),'${title}')] isDisplayed=True message=Updated Glossary value was not applied, check P&S
+ ELSE
+ Yves: try reloading page if element is/not appear: element=xpath=//h1[contains(@class,'title')][contains(text(),'${title}')] isDisplayed=True message=Updated Glossary value was not applied, check P&S
+ END
+
+Yves: login after signup during checkout:
+ [Arguments] ${email} ${password}
+ Type Text ${email_field} ${email}
+ Type Text ${password_field} ${password}
+ Click ${form_login_button}
+ Page Should Not Contain Element locator=${form_login_button} timeout=10s
+
+Yves: checkout is blocked with the following message:
+ [Arguments] ${expectedMessage}
+ ${currentURL}= Get Url
+ IF '/cart' in '${currentURL}'
+ ${checkout_button_state}= Get Element Attribute ${shopping_cart_checkout_button} class
+ Should Contain ${checkout_button_state} disabled
+ Get Text ${shopping_cart_checkout_error_message_locator} contains ${expectedMessage}
+ ELSE
+ TRY
+ Element Should Be Visible ${checkout_summary_alert_message}[${env}]
+ Page Should Not Contain Element ${checkout_summary_submit_order_button}
+ ${actualAlertMessage}= Get Text ${checkout_summary_alert_message}[${env}]
+ Should Be Equal ${actualAlertMessage} ${expectedMessage}
+ EXCEPT
+ Yves: accept the terms and conditions: true
+ Click ${checkout_summary_submit_order_button}
+ Yves: flash message should be shown: error ${expectedMessage}
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/common/common_zed.robot b/atest/testdata/performance/resources/common/common_zed.robot
new file mode 100755
index 0000000..2b3a6e4
--- /dev/null
+++ b/atest/testdata/performance/resources/common/common_zed.robot
@@ -0,0 +1,765 @@
+*** Settings ***
+Resource common_ui.robot
+Resource ../pages/zed/zed_login_page.robot
+Resource ../pages/zed/zed_edit_product_page.robot
+
+*** Variables ***
+${zed_log_out_button} xpath=//ul[@class='nav navbar-top-links navbar-right']//a[contains(@href,'logout')]
+${zed_save_button} xpath=//input[contains(@class,'safe-submit')]
+${zed_success_flash_message} xpath=//div[@class='flash-messages']/div[@class='alert alert-success']
+${zed_error_flash_message} xpath=//div[@class='flash-messages']/div[@class='alert alert-danger']
+${zed_info_flash_message} xpath=//div[@class='flash-messages']/../div[@class='alert alert-info']
+${zed_error_message} xpath=//div[@class='alert alert-danger']
+${zed_table_locator} xpath=//table[contains(@class,'dataTable')]/tbody
+${zed_search_field_locator} xpath=//div[@class='dataTables_filter']//input[@type='search']
+${zed_variant_search_field_locator} xpath=//*[@id='product-variant-table_filter']//input[@type='search']
+${zed_processing_block_locator} xpath=//div[contains(@id,'processing')][contains(@class,'dataTables_processing')]
+${zed_merchants_dropdown_locator} xpath=//select[@name='id-merchant']
+${zed_attribute_access_denied_header} xpath=//div[@class='wrapper wrapper-content']//div[@class='flash-messages']//following-sibling::h1
+${sweet_alert_js_error_popup} xpath=//*[contains(@class,'sweet-alert')]
+
+
+*** Keywords ***
+Zed: login on Zed with provided credentials:
+ [Arguments] ${email} ${password}=${default_password}
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Disable Automatic Screenshots on Failure
+ ${is_zed_url_accessible} Run Keyword And Ignore Error Zed: go to URL: /
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_zed_url_accessible
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ Zed: go to URL: /
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${is_login_page}= Run Keyword And Ignore Error Page Should Contain Element ${zed_user_name_field} timeout=10ms
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_login_page
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Zed: go to URL: /
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${zed_user_name_field}
+ ${email_value}= Convert To Lower Case ${email}
+ IF '+merchant+' in '${email_value}' VAR ${password} ${default_secure_password}
+ Type Text ${zed_user_name_field} ${email}
+ Type Text ${zed_password_field} ${password}
+ # workaround for the issue with deadlocks on concurrent login attempts
+ ${is_5xx}= Click and return True if 5xx occurred: ${zed_login_button}
+ IF ${is_5xx}
+ Delete All Cookies
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Zed: go to URL: /
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${zed_user_name_field}
+ ${email_value}= Convert To Lower Case ${email}
+ IF '+merchant+' in '${email_value}' VAR ${password} ${default_secure_password}
+ Type Text ${zed_user_name_field} ${email}
+ Type Text ${zed_password_field} ${password}
+ Click ${zed_login_button}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait Until Element Is Visible ${zed_log_out_button} Zed: Login failed! timeout=15s
+ EXCEPT
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ Zed: go to URL: /
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible ${zed_user_name_field}
+ ${email_value}= Convert To Lower Case ${email}
+ IF '+merchant+' in '${email_value}' VAR ${password} ${default_secure_password}
+ Type Text ${zed_user_name_field} ${email}
+ Type Text ${zed_password_field} ${password}
+ Click ${zed_login_button}
+ Wait Until Element Is Visible ${zed_log_out_button} Zed: Login failed! timeout=15s
+ END
+
+Zed: login with deactivated user/invalid data:
+ [Arguments] ${email} ${password}=${default_password}
+ Delete All Cookies
+ Zed: go to URL: /
+ Delete All Cookies
+ Reload
+ Wait Until Element Is Visible ${zed_user_name_field}
+ Type Text ${zed_user_name_field} ${email}
+ Type Text ${zed_password_field} ${password}
+ Click ${zed_login_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not fully loaded
+ END
+ Wait Until Element Is Visible xpath=//*[contains(text(), 'Authentication failed!')] timeout=10s
+
+Zed: go to first navigation item level:
+ [Documentation] example: "Zed: Go to First Navigation Item Level Customers"
+ [Arguments] ${navigation_item}
+ Wait Until Page Contains Element xpath=//ul[@id='side-menu']/li/a/span[@class='nav-label'][contains(text(),'${navigation_item}')]/../../a
+ Click Element by xpath with JavaScript //ul[@id='side-menu']/li/a/span[@class='nav-label'][contains(text(),'${navigation_item}')]/../../a
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ # workaround for the issue with deadlocks on concurrent search attempts
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error} Log ''sweet-alert' js error popup on the page '${zed_url}: ${navigation_item}'
+ END
+ END
+
+Zed: go to second navigation item level:
+ [Documentation] example: "Zed: Go to Second Navigation Item Level Customers Customer Access"
+ [Arguments] ${navigation_item_level1} ${navigation_item_level2}
+ ${node_state}= Get Element Attribute xpath=(//span[contains(@class,'nav-label')][text()='${navigation_item_level1}']/ancestor::li)[1] class
+ IF 'active' in '${node_state}'
+ wait until element is visible xpath=(//ul[contains(@class,'nav-second-level')]//a/span[text()='${navigation_item_level2}'])[1]
+ Click Element by xpath with JavaScript (//span[contains(@class,'nav-label')][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'nav-second-level')]//a/span[text()='${navigation_item_level2}'])[1]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ELSE
+ Scroll Element Into View xpath=//ul[@id='side-menu']/li/a/span[@class='nav-label'][contains(text(),'${navigation_item_level1}')]/../../a
+ Click Element by xpath with JavaScript //ul[@id='side-menu']/li/a/span[@class='nav-label'][contains(text(),'${navigation_item_level1}')]/../../a
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${node_expanded}= Run Keyword And Return Status Element Should Be Visible xpath=//span[contains(@class,'nav-label')][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'nav-second-level')]//a/span[text()='${navigation_item_level2}'] timeout=500ms
+ Restore Automatic Screenshots on Failure
+ IF '${node_expanded}'=='False'
+ Reload
+ Click xpath=//ul[@id='side-menu']/li/a/span[@class='nav-label'][contains(text(),'${navigation_item_level1}')]/../../a
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ wait until element is visible xpath=(//span[contains(@class,'nav-label')][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'nav-second-level')]//a/span[text()='${navigation_item_level2}'])[1]
+ Click Element by xpath with JavaScript (//span[contains(@class,'nav-label')][text()='${navigation_item_level1}']/ancestor::li//ul[contains(@class,'nav-second-level')]//a/span[text()='${navigation_item_level2}'])[1]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ # workaround for the issue with deadlocks on concurrent search attempts
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=100ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=100ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=100ms
+ IF not ${no_js_error} Log ''sweet-alert' js error popup on the page '${zed_url}: ${navigation_item_level1}->${navigation_item_level2}'
+ END
+ END
+
+Zed: click button in Header:
+ [Arguments] ${button_name}
+ Wait Until Element Is Visible xpath=//div[@class='title-action']/a[contains(.,'${button_name}')]
+ Click and retry if 5xx occurred: xpath=//div[@class='title-action']/a[contains(.,'${button_name}')]
+
+Zed: wait for button in Header to be visible:
+ [Arguments] ${button_name} ${timeout}
+ Wait until element is visible xpath=//div[@class='title-action']/a[contains(.,'${button_name}')]
+
+Zed: click Action Button in a table for row that contains:
+ [Arguments] ${row_content} ${zed_table_action_button_locator}
+ Zed: perform search by: ${row_content}
+ Wait until element is visible xpath=(//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}') and not(contains(text(),'service'))]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')])[1]
+ Click and retry if 5xx occurred: xpath=(//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}') and not(contains(text(),'service'))]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')])[1]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Zed: save abstract product:
+ [Arguments] ${productAbstract} ${admin_email}=${zed_admin_email}
+ ${currentURL}= Get Location
+ ${dynamic_admin_user_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ IF ${dynamic_admin_user_exists} and '${admin_email}' == '${zed_admin_email}'
+ VAR ${admin_email} ${dynamic_admin_user}
+ ELSE IF not ${dynamic_admin_user_exists}
+ VAR ${admin_email} ${zed_admin_email}
+ END
+ IF '${zed_url}' not in '${currentURL}' or '${zed_url}security-gui/login' in '${currentURL}'
+ Zed: login on Zed with provided credentials: ${admin_email}
+ END
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ Wait until element is visible ${zed_save_button}
+ Zed: submit the form
+
+Zed: click Action Button in Variant table for row that contains:
+ [Arguments] ${row_content} ${zed_table_action_button_locator}
+ Zed: perform variant search by: ${row_content}
+ wait until element is visible xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
+ # workaround for the issue with deadlocks on concurrent search attempts
+ Click and retry if 5xx occurred: xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Zed: Check checkbox by Label:
+ [Arguments] ${checkbox_label}
+ wait until element is visible xpath=(//label[contains(., '${checkbox_label}')]//input[@type='checkbox'])[1]
+ Check checkbox xpath=(//label[contains(., '${checkbox_label}')]//input[@type='checkbox'])[1]
+
+Zed: Check checkbox by Value:
+ [Arguments] ${checkbox_value}
+ wait until element is visible xpath=//input[@type='checkbox' and contains(@value, '${checkbox_value}')]
+ Check checkbox xpath=//input[@type='checkbox' and contains(@value, '${checkbox_value}')]
+
+Zed: Uncheck Checkbox by Label:
+ [Arguments] ${checkbox_label}
+ wait until element is visible xpath=(//label[contains(., '${checkbox_label}')]//input[@type='checkbox'])[1]
+ Uncheck Checkbox xpath=(//label[contains(., '${checkbox_label}')]//input[@type='checkbox'])[1]
+
+Zed: submit the form
+ Wait until element is visible ${zed_save_button}
+ Click ${zed_save_button}
+ # workaround for the issue with deadlocks on concurrent search attempts
+ ${got_response}= Run Keyword And Ignore Error Wait For Response
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${zed_log_out_button}
+ ${error_flash_message}= Run Keyword And Ignore Error Page Should Not Contain Element ${zed_error_flash_message} 1s
+ IF 'FAIL' in $got_response
+ ${page_contains_target_element}= Run Keyword And Return Status Page Should Contain Element ${zed_save_button} timeout=10ms
+ IF ${page_contains_target_element}
+ Click ${zed_save_button}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${zed_log_out_button}
+ END
+ IF 'FAIL' in $error_flash_message
+ Click ${zed_save_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${zed_log_out_button}
+ END
+ Disable Automatic Screenshots on Failure
+ ${error_message}= Run Keyword And Ignore Error Page Should Not Contain Element ${zed_error_message} 1s
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $error_message
+ Click ${zed_save_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${zed_log_out_button}
+ END
+ Page Should Not Contain Element ${zed_error_message} 1s
+ Page Should Not Contain Element ${zed_error_flash_message} 1s
+
+Zed: perform search by:
+ [Arguments] ${search_key}
+ # Build two safe regex fragments for the search value:
+ # - enc1: percent-encoded, spaces -> %20
+ # - enc2: form-encoded, spaces -> +
+ ${enc1}= Evaluate re.escape(urllib.parse.quote("""${search_key}""")) modules=re,urllib.parse
+ ${enc2}= Evaluate re.escape(urllib.parse.quote_plus("""${search_key}""")) modules=re,urllib.parse
+
+ # Table-agnostic JS RegExp literal; match full search[value] (case-insensitive)
+ ${search_matcher}= Set Variable /[?&]search%5Bvalue%5D=(?:${enc1}|${enc2})(?:&|$)/i
+ Zed: clear search field
+ # --- main attempt ---
+ TRY
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_search_field_locator} ${search_key}
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ IF '${result}[0]'=='FAIL'
+ Log Search event failed level=WARN
+ VAR ${is_5xx} ${False}
+ ELSE
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ ${is_5xx}= Evaluate ${status} >= 500
+ IF ${is_5xx}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Zed: clear search field
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ END
+ END
+ EXCEPT
+ # --- recovery path if exception thrown ---
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Zed: clear search field
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ END
+ # Final settle
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ # Handle any SweetAlert JS error popup with a re-attempt
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Zed: clear search field
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error} Fail ''sweet-alert' js error popup occurred'
+ END
+
+Zed: clear search field
+ Clear Text ${zed_search_field_locator}
+ # workaround for the issue with deadlocks on concurrent search attempts
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Clear Text ${zed_search_field_locator}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error} Fail ''sweet-alert' js error popup occurred'
+ END
+
+Zed: perform variant search by:
+ [Arguments] ${search_key}
+ # Two safe regex fragments for the full search term:
+ # enc1: percent-encoded (spaces -> %20)
+ # enc2: form-encoded (spaces -> +)
+ ${enc1}= Evaluate re.escape(urllib.parse.quote("""${search_key}""")) modules=re,urllib.parse
+ ${enc2}= Evaluate re.escape(urllib.parse.quote_plus("""${search_key}""")) modules=re,urllib.parse
+
+ # Table-agnostic JS RegExp literal; matches full search[value] in URL (case-insensitive)
+ ${search_matcher}= Set Variable /[?&]search%5Bvalue%5D=(?:${enc1}|${enc2})(?:&|$)/i
+ Clear Text ${zed_variant_search_field_locator}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+
+ # Main attempt: promise BEFORE typing to avoid race conditions
+ TRY
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_variant_search_field_locator} ${search_key}
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+
+ IF '${result}[0]'=='FAIL'
+ Log Search by concrete event failed level=WARN
+ VAR ${is_5xx} ${False}
+ ELSE
+ ${response}= Set Variable ${result}[1]
+ ${status}= Get From Dictionary ${response} status
+ ${is_5xx}= Evaluate ${status} >= 500
+ IF ${is_5xx}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Clear Text ${zed_variant_search_field_locator}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_variant_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ END
+ END
+ EXCEPT
+ # Recovery path
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Clear Text ${zed_variant_search_field_locator}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_variant_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ END
+ # Final settle
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ # JS error popup handling
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Reload
+ Clear Text ${zed_variant_search_field_locator}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_variant_search_field_locator} ${search_key}
+ TRY
+ Wait For ${promise}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Search event is not fired
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=500ms
+ IF not ${no_js_error} Fail ''sweet-alert' js error popup occurred'
+ END
+
+Zed: table should contain:
+ [Arguments] ${search_key} ${error_message}=Table doesn't contain expected '${search_key}' record
+ Zed: perform search by: ${search_key}
+ Table Should Contain locator=${zed_table_locator} expected=${search_key} message=${error_message}
+
+Zed: table should contain non-searchable value:
+ [Arguments] ${search_key}
+ Wait Until Element Is Visible ${zed_table_locator}
+ Table Should Contain ${zed_table_locator} ${search_key}
+
+Zed: table should contain xxx N times:
+ [Arguments] ${search_key} ${expected_count}
+ Wait Until Element Is Visible ${zed_table_locator}
+ Zed: perform search by: ${search_key}
+ ${actual_count}= Get Element Count xpath=//table[contains(@class,'dataTable')]/tbody//*[contains(text(),'${search_key}')]
+ Should Be Equal '${actual_count}' '${expected_count}'
+
+Zed: go to tab:
+ [Arguments] ${tabName}
+ ${is_5xx}= Click and return True if 5xx occurred: xpath=//*[contains(@data-bs-toggle,'tab') and contains(text(),'${tabName}')]
+ # workaround for the issue with deadlocks on concurrent click attempts
+ IF ${is_5xx}
+ Reload
+ Click With Options xpath=//*[contains(@data-bs-toggle,'tab') and contains(text(),'${tabName}')] force=True noWaitAfter=True
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+
+Zed: go to tab by link href that contains:
+ [Arguments] ${href}
+ ${is_5xx}= Click and return True if 5xx occurred: xpath=//*[contains(@data-bs-toggle,'tab')][contains(@data-bs-target,'${href}')] | //*[contains(@data-bs-toggle,'tab')]//li[contains(@data-bs-target,'${href}')]
+ # workaround for the issue with deadlocks on concurrent click attempts
+ IF ${is_5xx}
+ Reload
+ Click With Options xpath=//*[contains(@data-bs-toggle,'tab')][contains(@data-bs-target,'${href}')] | //*[contains(@data-bs-toggle,'tab')]//li[contains(@data-bs-target,'${href}')] force=True noWaitAfter=True
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+
+Zed: message should be shown:
+ [Arguments] ${text}
+ Wait Until Element Is Visible xpath=//div[contains(@class,'alert alert-success')]//*[contains(text(),'${text}')] message=Success message is not shown
+
+Zed: flash message should be shown:
+ [Documentation] Possible values: 'success', 'info' and 'danger'
+ [Arguments] ${type}=success
+ Wait Until Element Is Visible xpath=//div[contains(@class, 'flash-messages')]//div[contains(@class,'alert-${type}')] message=Flash message is not shown
+
+Zed: click Action Button(without search) in a table for row that contains:
+ [Arguments] ${row_content} ${zed_table_action_button_locator}
+ wait until element is visible xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
+ Click xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Zed: filter by merchant:
+ [Arguments] ${merchant}
+ Wait Until Element Is Visible ${zed_merchants_dropdown_locator}
+ Select From List By Label ${zed_merchants_dropdown_locator} ${merchant}
+
+Zed: is admin user is logged in
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not loaded
+ END
+ ${adminIsLoggedIn}= Run Keyword And Return Status Page Should Contain Element locator=${zed_log_out_button} timeout=0.1s
+ RETURN ${adminIsLoggedIn}
+
+Zed: go to URL:
+ [Arguments] ${url} ${expected_response_code}=${EMPTY}
+ ${url}= Get URL Without Starting Slash ${url}
+ Set Browser Timeout ${browser_timeout}
+ ${response_code}= Go To ${zed_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ # workaround for the issue with deadlocks on concurrent search attempts
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ ${no_exception}= Run Keyword And Return Status Should Not Contain ${page_title} error
+ IF ${is_5xx} or not ${no_exception}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ ${response_code}= Go To ${zed_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ IF ${is_5xx} Fail '${response_code}' error occurred on go to '${zed_url}${url}'
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${page_title}= Get Title
+ ${page_title}= Convert To Lower Case ${page_title}
+ Should Not Contain ${page_title} error msg='${response_code}' error occurred on go to '${zed_url}${url}'
+ END
+ IF '${expected_response_code}' != '${EMPTY}'
+ ${expected_response_code}= Convert To Integer ${expected_response_code}
+ Should Be Equal ${response_code} ${expected_response_code} msg=Expected response code (${expected_response_code}) is not equal to the actual response code (${response_code}) on Go to: ${zed_url}${url}
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=3s
+ IF not ${no_js_error}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ ${response_code}= Go To ${zed_url}${url}
+ ${response_code}= Convert To Integer ${response_code}
+ ${is_5xx}= Evaluate 500 <= ${response_code} < 600
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF ${is_5xx} Fail '${response_code}' error occurred on go to '${zed_url}${url}'
+ ${error_message}= Run Keyword And Return Status Page Should Not Contain Element ${zed_error_message} timeout=1s
+ ${error_flash_message}= Run Keyword And Return Status Page Should Not Contain Element ${zed_error_flash_message} timeout=1s
+ IF not ${error_message} or not ${error_flash_message}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ ${response_code}= Go To ${zed_url}${url}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ ${no_js_error}= Run Keyword And Return Status Element Should Not Be Visible ${sweet_alert_js_error_popup} timeout=3s
+ IF not ${no_js_error}
+ Take Screenshot EMBED fullPage=True
+ Log ''sweet-alert' js error popup on the page '${zed_url}${url}' level=WARN
+ END
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ RETURN ${response_code}
diff --git a/atest/testdata/performance/resources/environments/environments_api_b2b.json b/atest/testdata/performance/resources/environments/environments_api_b2b.json
new file mode 100644
index 0000000..a016d17
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_api_b2b.json
@@ -0,0 +1,662 @@
+{
+ "environment":"api_b2b",
+ "env":{
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "dataType": {
+ "array": []
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user":{
+ "email":"sonia@spryker.com",
+ "first_name":"Sonia",
+ "last_name":"Wagner",
+ "password":"change123",
+ "password_new":"qweRTY_123456",
+ "password_new_additional":"Change!23456",
+ "reference":"DE--21",
+ "salutation":"Ms"
+ },
+ "yves_second_user":{
+ "email":"bill.martin@spryker.com",
+ "first_name":"Martin",
+ "last_name":"Bill",
+ "password":"change123",
+ "reference":"DE--4",
+ "salutation":"Mr"
+ },
+ "yves_third_user":{
+ "email":"maxmusterman@spryker.com",
+ "first_name":"Max",
+ "last_name":"Musterman",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "salutation":"Mr"
+ },
+ "yves_fourth_user":{
+ "email":"Lilu@ottom.de",
+ "first_name":"Lilu",
+ "last_name":"Dallas",
+ "password":"change123",
+ "reference":"DE-30",
+ "salutation":"Ms"
+ },
+ "yves_fifth_user":{
+ "email":"Sarah@spryker.com",
+ "first_name":"Sarah",
+ "last_name":"Muller",
+ "password":"change123",
+ "reference":"DE-17",
+ "salutation":"Ms"
+ },
+ "yves_eighth_user":{
+ "email":"maria.williams@spryker.com",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "password_new_additional":"qweRTY_123456",
+ "reference":"DE--2"
+ },
+ "yves_ninth_user":{
+ "email":"maggie.may@spryker.com",
+ "first_name":"Maggie",
+ "last_name":"May",
+ "password":"Change!23456",
+ "password_new":"qweRTY_123456",
+ "reference":"DE--3",
+ "salutation":"Ms"
+ },
+ "yves_ottom_admin_user":{
+ "email":"andrew@ottom.de",
+ "first_name":"Andrew",
+ "last_name":"Wedner",
+ "password":"change123",
+ "reference":"DE-8",
+ "salutation":"Mr"
+ },
+ "yves_shared_shopping_list_user":{
+ "email":"Trever.m@spryker.com",
+ "first_name":"Trever",
+ "last_name":"Meier",
+ "password":"change123",
+ "salutation":"Mr"
+ },
+ "yves_shared_shopping_cart_user":{
+ "email":"Solomon@spryker.com",
+ "first_name":"Solomon",
+ "last_name":"Wesner",
+ "password":"change123",
+ "salutation":"Mr"
+ },
+ "gender":{
+ "female":"Female",
+ "male":"Male"
+ },
+ "email":{
+ "name":"sonia",
+ "domain":"@spryker.com"
+ },
+ "zed_admin":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "agent":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "non_agent":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "customer_reference":{
+ "de_1":"DE--1",
+ "de_10":"DE--10",
+ "de_15":"DE--15",
+ "de_34":"DE--34"
+ },
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ }
+ },
+ "address":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"false",
+ "billing_status":"false"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ }
+ },
+ "shopping_list":{
+ "shopping_list_name":"My Shopping List",
+ "shopping_list_1st":{
+ "id":"cf032865-d1ad-5e27-803a-423bd15ced66",
+ "name":"Newcomers"
+ },
+ "shopping_list_2":{
+ "name":"Weekly office"
+ },
+ "shopping_list_3":{
+ "name":"Monthly office"
+ }
+ },
+ "search":{
+ "default_qty":{
+ "categories":"37",
+ "categories_ssp":"38",
+ "colors":"10",
+ "labels":"5",
+ "labels_ssp":"8",
+ "materials":"10",
+ "brands":"10",
+ "ipp_pages":"35",
+ "ipp_pages_ssp":"36",
+ "sorting_options":"5"
+ },
+ "ipp":{
+ "default":"12",
+ "middle":"24",
+ "biggest":"36"
+ },
+ "default_rating":{
+ "min":"4",
+ "max":"5"
+ },
+ "label":{
+ "new":"New",
+ "sale":"SALE %",
+ "manual":"Top",
+ "discontinued":"Discontinued",
+ "alternatives":"Alternatives available"
+ },
+ "category_lvl1":{
+ "id":"11",
+ "qty":"172"
+ },
+ "category_lvl2":{
+ "id":"12",
+ "qty":"56",
+ "qty_approx":"50"
+ },
+ "category_lvl3":{
+ "id":"13",
+ "qty":"28"
+ },
+ "category_tree_branches_qty":"6",
+ "category_tree_branches_qty_ssp":"7",
+ "total_number_of_products_in_search":"420",
+ "total_number_of_products_in_search_ssp":"424",
+ "abstract_sku_highest_rating":"M1016129"
+ },
+ "products":{
+ "bundle_product":{
+ "product_1":{
+ "abstract_sku":"B0001",
+ "concrete_sku":"000101",
+ "name":"Our Favourite Workspace Bundle"
+ },
+ "product_2":{
+ "abstract_sku":"M528",
+ "concrete_sku":"104939",
+ "name":"Dauphin vertebral disc swivel chair, synchronous mechanism"
+ },
+ "product_3":{
+ "abstract_sku":"M1017905",
+ "concrete_sku":"574995",
+ "name":"UPLINER standing desk, electric - without traverse, WxD 1800 x 800 mm - substructure silver, light gray"
+ },
+ "product_4":{
+ "abstract_sku":"M24605",
+ "concrete_sku":"426581",
+ "name":"Cherry keyboard Strait JK-0300DE metal-look, corded, USB, silver"
+ },
+ "qty_of_products_in_bundle":"3",
+ "qty_of_each_product_inside_bundle":"1"
+ },
+ "concrete":{
+ "with_relations_upselling_sku":"419872",
+ "unavailable_products_sku":"212447",
+ "volume_prices_sku":"420685",
+ "with_promotions_sku":"212427",
+ "alternative_products":{
+ "product_1":{
+ "sku":"420566",
+ "name":"Verbatim USB stick Store n Go V3 49173 32GB USB3.0 gray",
+ "name_in_lower_case":"verbatim usb stick store n go v3 49173 32gb usb3.0 gray"
+ },
+ "with_relations_upselling_sku":"419880"
+ },
+ "available_product":{
+ "with_stock":{
+ "product_1":{
+ "sku":"102712",
+ "meta_keywords":"Arbeitsdrehstuhl,Bandscheibendrehstuhl,Bandschreibendrehstuhl,Bürodrehstuhl,Bürostuhl,Drehstuhl,Schreibtischstuhl,Universalstuhl",
+ "meta_description":" Pflegeleichter Stoffbezug. Gestell in Graphitschwarz RAL 9011.
Standardmäßig Rollen für weiche Böden.
Die Rückenlehne verfügt über eine höhenverstellbare Lendenwirbelstütze. "
+ },
+ "product_2":{
+ "sku":"420566"
+ }
+ },
+ "with_stock_and_never_out_of_stock":{
+ "sku":"657716",
+ "name":"FRIWA stackable chair - with closed back"
+ },
+ "without_stock":{
+ "sku":"212447"
+ }
+ },
+ "with_original_prices":{
+ "sku":"420687",
+ "name":"Post-it Index Strong adhesive stripes, 686-F1EU 4 sheets sorted, 4 pieces/pack"
+ },
+ "with_options":{
+ "sku":"419871",
+ "name":"Safescan automatic banknote counter, UV Counterfeit recognition, SAFESCAN 2210"
+ },
+ "one_image_set":{
+ "sku":"401768",
+ "name":"EUROKRAFT aluminum hand truck - Load capacity 200 kg, with skids - load capacity 200 kg"
+ },
+ "multiple_image_set":{
+ "sku":"212427",
+ "name":"Wood stackable chair, upholstered - VE 4 pieces, substructure chromed - upholstery black"
+ },
+ "random_weight":{
+ "sku":"cable-vga-1-2",
+ "sku1":"cable-vga-1-1",
+ "name":"VGA cable as long as you want",
+ "name1":"VGA cable (1.5m)",
+ "measurement_unit":"19",
+ "qty_of_units":"2",
+ "amount":"5.0000000000",
+ "amount1":"1.5000000000",
+ "conversion":"1",
+ "conversion1":"1",
+ "precision":"100",
+ "precision1":"100",
+ "packaging_unit":"19",
+ "packaging_unit1":"18"
+ },
+ "with_brand_safescan":{
+ "product_1":{
+ "sku":"419872"
+ },
+ "product_2_and_white_color":{
+ "sku":"419901"
+ }
+ }
+ },
+ "abstract":{
+ "product_in_different_locales":{
+ "sku":"M29455",
+ "description_de":"Alu-Datenentsorgungsbehälter",
+ "description_en":"Aluminum data disposal container"
+ },
+ "upselling_products_sku":"M29502",
+ "special_product_abstract_sku":{
+ "with_multivariant":"M58035",
+ "with_measurement_unit":"M23723",
+ "with_packaging_unit":"M21766"
+ },
+ "product_with_relations":{
+ "has_related_products":{
+ "product_1":{
+ "sku":"M29529"
+ },
+ "product_2":{
+ "sku":"M29501",
+ "name":"Safescan automatic banknote counter - UV counterfeit recognition"
+ },
+ "has_upselling_product":{
+ "sku":"M29499",
+ "name":"Safescan counterfeit test device - SAFESCAN 45 UV"
+ }
+ }
+ },
+ "alternative_products":{
+ "product_1":{
+ "sku":"M21100",
+ "price_de":"1579",
+ "price_at":"1679",
+ "name":"Verbatim USB stick Store n Go V3 49173 32GB USB3.0 gray"
+ },
+ "product_2":{
+ "sku":"M90810",
+ "price_chf":"1130"
+ },
+ "product_3":{
+ "sku":"M21099",
+ "name":"Verbatim USB stick Store n Go V3 49172 16GB USB3.0, gray",
+ "price_chf":"1130"
+ }
+ },
+ "available_products":{
+ "with_stock":{
+ "sku":"M61125",
+ "name":"Prosedia vertebral disc swivel chair with synchronous mechanics and contoured seat - backrest height 660 mm",
+ "description":" Easy-to-care-for fabric cover. Substructure in graphite black RAL 9011.
Standard rolling for soft floors.
The backrest has height-adjustable lumbar support. ",
+ "superattribute":"bezugsfarbe"
+ },
+ "with_stock_and_never_out_of_stock_sku":"M87",
+ "with_stock_and_never_out_of_stock_sku_2":"M719",
+ "with_no_stock_and_never_out_of_stock_sku":"M90851",
+ "with_3_concretes":{
+ "sku":"M29456",
+ "name":"Gmöhling aluminum data removal container - Exterior - LxWxH 435 x 385 x 650 mm",
+ "superattribute":"material"
+ }
+ },
+ "unavailable_product_sku":"M1014948",
+ "volume_prices":{
+ "sku":"M21189",
+ "name":"Post-it stick note Super Sticky Meeting Notes 6445-4SS 4 pieces/pack"
+ },
+ "original_prices":{
+ "sku":"M74972"
+ },
+ "with_label":{
+ "sku":"M21691",
+ "name":"Clairefontaine Collegeblock 8272C DIN A5, 90 sheets"
+ },
+ "with_review":{
+ "sku":"M719",
+ "name":"Rectangular table, rectangular tubing - 1600 x 800 mm",
+ "qty":"4"
+ },
+ "with_options":{
+ "sku":"M29501",
+ "name":"Safescan automatic banknote counter - UV counterfeit recognition"
+ }
+ },
+ "packaging_unit":{
+ "m":"METR",
+ "cm":"CMET",
+ "m_name":"Meter",
+ "m_name2":"Centimeter"
+ },
+ "measurement_unit":{
+ "m":"METR"
+ },
+ "product_options":{
+ "option_1":"OP_2_year_waranty",
+ "option_1_name":"Two (2) year limited warranty",
+ "option_2":"OP_insurance"
+ },
+ "discount":{
+ "product_1":{
+ "sku":"108298",
+ "name":"Mauser hinged door cabinet - sideboard, 4 compartments, center separating wall - HxWxD 1225 x 1600 x 420 mm - light gray / ultramarine blue",
+ "with_discount_20_percent_off_storage":"10600",
+ "with_discount_10_percent_off_minimum_order":"4240",
+ "total_sum_of_discounts":"14840"
+ },
+ "product_2":{
+ "sku":"213216",
+ "name":"office akktiv base cabinet - HxWxD 942 x 913 x 420 mm - light gray, RAL 7035",
+ "with_discount_20_percent_off_storage":"5783",
+ "with_discount_10_percent_off_minimum_order":"2313",
+ "total_sum_of_discounts":"8096"
+ },
+ "product_3":{
+ "sku":"401768",
+ "name":"EUROKRAFT aluminum hand truck - Load capacity 200 kg, with skids - load capacity 200 kg",
+ "with_discount_20%_off_storage":"16383",
+ "with_10_percent_discount_amount":"1882"
+ }
+ },
+ "voucher":{
+ "brand_safescan_2_items":"782",
+ "brand_safescan_and_white_color_2_items":"3201"
+ },
+ "configurable_bundle":{
+ "template_id":"8d8510d8-59fe-5289-8a65-19f0c35a0089",
+ "template_name":"Office bundle",
+ "first_slot_item_sku":"575056",
+ "first_slot_uuid":"332b40ac-a789-57ce-bec0-23d8dddd71eb",
+ "quantity":2
+ },
+ "configurable_product": {
+ "sku": "574601",
+ "name":"CP steel cabinet, fire-resistant - 3 adjustable shelves - 1 locker - black gray / light gray"
+ }
+
+ },
+ "product_attributes":{
+ "brand_1":"Soennecken",
+ "brand_2":"edding",
+ "brand_3":"Mauser",
+ "brand_4":"Prosedia",
+ "material_1":"aluminum",
+ "material_2":"metal",
+ "material_3":"chipboard",
+ "material_4":"Steel sheets, stove-enameled",
+ "delivery_1":"assembled",
+ "price_unit_1":"piece",
+ "color_3":"purple",
+ "color_1":"yellow",
+ "color_2":"blue",
+ "product_management":{
+ "superattribute_id":"farbe",
+ "attribute_free_input_id":"verschlussart",
+ "attribute_no_input_id":"bundled_product"
+ },
+ "norm_1":"DIN EN 1335 Part 1 – 3, DIN EN 12527 + DIN EN 12529",
+ "rollenausfuehrung_1":"rollers for soft floors",
+ "sitzschalenform_1":"Contoured seat"
+ },
+ "content":{
+ "abstract_list":{
+ "id":"apl-1",
+ "product1_sku":"M21692",
+ "product1_name":"Clairefontaine Collegeblock 8272C DIN A5, 90 sheets",
+ "product2_sku":"M23723",
+ "product2_name":"Brennenstuhl extension cable 3 m",
+ "size":"8"
+ },
+ "banner":{
+ "id":"br-1",
+ "name":"Furniture - Upgrade Your Office"
+ },
+ "cms_page":{
+ "qty":"5",
+ "name":"Imprint",
+ "name_in_lower_case":"imprint",
+ "url_en":"/en/imprint",
+ "product_lists_id":"10014bd9-4bba-5a54-b84f-31b4b7efd064",
+ "product_lists_name":"Demo Landing Page",
+ "collection_name":"GTC",
+ "collection_url":"/en/gtc"
+ },
+ "category_collection":{
+ "name":"Sticky Notes",
+ "url":"/en/stationery/paper/sticky-notes"
+ },
+ "category_node":{
+ "root_id":"1",
+ "has_only_parent_id":"37",
+ "has_children_id":"11",
+ "storage_name":"Foods",
+ "storage_url":"/en/foods"
+ },
+ "subcategory_node":{
+ "storage_name":"Vegetables",
+ "storage_url":"/en/foods/vegetables",
+ "storage_name_2":"Fish",
+ "storage_url_2":"/en/foods/fish"
+ },
+
+ "brand_name":"verbatim",
+ "cart_permission_group_id":"1"
+ },
+ "availability":{
+ "stock_is_0":"0.0000000000",
+ "stock_is_20":"20.0000000000"
+ },
+ "misc":{
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "test_cart_name":"Test-cart",
+ "restricted_content_qty":"5",
+ "qty_of_categories_in_category_trees":"6",
+ "qty_of_categories_in_category_trees_ssp":"7",
+ "qty_of_subcategories_in_category_trees":"2",
+ "color_name":"black",
+ "payment_provider_name":"DummyPayment",
+ "payment_method_name":"Invoice",
+ "shipment_method":{
+ "carrier_name":"DHL",
+ "name":"Standard",
+ "delivery_date":"2030-12-31",
+ "name_2":"Express"
+ },
+ "shipment":{
+ "carrier_name":"DHL",
+ "delivery_date":"2030-12-31",
+ "shipment_method1":{
+ "name":"Standard"
+ },
+ "shipment_method2":{
+ "name":"Express"
+ }
+ },
+ "review":{
+ "title":"This is a review",
+ "text":"This is review text",
+ "default_rating":"5"
+ },
+ "discounts":{
+ "discount_1":{
+ "name":"20% off storage",
+ "description":"Storage sale: 20% off all office storage products",
+ "total_sum_for_products_1_and_2":"16383"
+ },
+ "discount_2":{
+ "name":"10% off minimum order",
+ "description":"Get a 10% discount on all orders above a certain value depending on currency and gross/net price mode",
+ "total_sum_for_discounts_for_products_1_2_and_3":"8435"
+ },
+ "discount_3":{
+ "name":"Free standard delivery",
+ "description":"Free standard delivery for all orders above certain value depending on the currency",
+ "total_sum":"490"
+ },
+ "id_3":{
+ "name":"5% off white",
+ "description":"Get a 5% discount on all white products with voucher code"
+ },
+ "id_4":{
+ "name":"10% off Safescan",
+ "description":"Get a 10% discount on all Safescan brand products with voucher code"
+ }
+ },
+ "cart_rule_name_10_off_minimum_order":"10% off minimum order",
+ "url_resolver":{
+ "example":"/en/clairefontaine-collegeblock-8272c-din-a5-90blatt-kariert-M21692",
+ "entity_type":"abstract-products",
+ "entity_id":"M21692"
+ }
+ },
+ "companies":{
+ "company_name":"Spryker Systems GmbH",
+ "busines_unit_address_id":"2175cddd-f8af-5885-b161-227b5c93e72f",
+ "business_unit_name":"Spryker Systems HR department",
+ "user_with_multiple_companies":"anne.boleyn@spryker.com",
+ "company_id":"62de4ab6-b768-5c21-8835-455d9f341625",
+ "company_user_id":"2816dcbd-855e-567e-b26f-4d57f3310bb8"
+ },
+ "labels":{
+ "labels":{
+ "id_manual":"3",
+ "name_manual":"Top",
+ "id_sale":"5",
+ "name_sale":"SALE %",
+ "id_new":"4",
+ "name_new":"New",
+ "id_discontinued":"2",
+ "name_discontinued":"Discontinued",
+ "id_alternative":"1",
+ "name_alternative":"Alternatives available"
+ }
+ },
+ "return_reasons":{
+ "return_reason":{
+ "damaged":"Damaged",
+ "wrong_item":"Wrong Item",
+ "no_longer_needed":"No longer needed",
+ "qty":"3"
+ }},
+ "productConfigurationInstance": {
+ "productConfigurationInstance":{
+ "displayData": "{\"Preferred time of the day\": \"Afternoon\", \"Date\": \"9.09.2050\"}",
+ "configuration": "{\"time_of_day\": \"3\"}",
+ "configuratorKey": "DATE_TIME_CONFIGURATOR",
+ "isComplete": true
+ }
+ },
+ "dummy_api_key":"eba8110c9f9bf5685e8b5f4eba9b17c2",
+ "dummy_key_hash":"f683f48de788d57cd396fc212ef33fd146e1ff0b51cde37ecb4ddd77eeed1706"
+ }
diff --git a/atest/testdata/performance/resources/environments/environments_api_b2c.json b/atest/testdata/performance/resources/environments/environments_api_b2c.json
new file mode 100755
index 0000000..622af20
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_api_b2c.json
@@ -0,0 +1,743 @@
+{
+ "environment":"api_b2c",
+ "env":{
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user":{
+ "email":"sonia@spryker.com",
+ "first_name":"Sonia",
+ "last_name":"Wagner",
+ "password":"change123",
+ "password_new":"qweRTY_123456",
+ "password_new_additional":"Change!23456",
+ "reference":"DE--21",
+ "salutation":"Ms"
+ },
+ "yves_second_user":{
+ "email":"bill.martin@spryker.com",
+ "first_name":"Bill",
+ "last_name":"Martin",
+ "password":"change123",
+ "reference":"DE--4",
+ "salutation":"Mr"
+ },
+ "yves_third_user":{
+ "email":"maxmusterman@spryker.com",
+ "first_name":"Max",
+ "last_name":"Musterman",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "salutation":"Mr"
+ },
+ "yves_eighth_user":{
+ "email":"maria.williams@spryker.com",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "password_new_additional":"qweRTY_123456",
+ "reference":"DE--2"
+ },
+ "yves_ninth_user":{
+ "email":"maggie.may@spryker.com",
+ "first_name":"Maggie",
+ "last_name":"May",
+ "password":"Change!23456",
+ "password_new":"qweRTY_123456",
+ "reference":"DE--3",
+ "salutation":"Ms"
+ },
+ "gender":{
+ "female":"Female",
+ "male":"Male"
+ },
+ "email":{
+ "name":"sonia",
+ "domain":"@spryker.com"
+ },
+ "zed_admin":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "agent":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "non_agent":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "customer_reference":{
+ "de_1":"DE--1",
+ "de_10":"DE--10",
+ "de_15":"DE--15",
+ "de_34":"DE--34"
+ },
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ }
+ },
+ "address":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"false",
+ "billing_status":"false"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ }
+ },
+ "search":{
+ "total_number_of_products_in_search":"215",
+ "total_number_of_products_in_search_CHF":"215",
+ "ipp":{
+ "default":"12",
+ "middle":"24",
+ "biggest":"36"
+ },
+ "default_qty":{
+ "ipp_pages":"18",
+ "categories":"15",
+ "colors":"10",
+ "weight":"10",
+ "labels":"4",
+ "materials":"10",
+ "storage_capacity":"5",
+ "touchscreen":"2",
+ "brands":"10"
+ },
+ "default_rating":{
+ "min":"4",
+ "max":"5"
+ },
+ "default_price":{
+ "min":"0",
+ "max":"345699"
+ },
+ "sorting_options":{
+ "qty":"5"
+ },
+ "label":{
+ "new_id":"4",
+ "new":"New",
+ "sale_id":"5",
+ "sale":"SALE %",
+ "manual":"Top",
+ "discontinued_id":"2",
+ "discontinued":"Discontinued",
+ "alternatives_id":"1",
+ "alternatives":"Alternatives available"
+ },
+ "category_lvl1":{
+ "id":"11",
+ "qty":"39"
+ },
+ "category_lvl2":{
+ "id":"12",
+ "qty":"38"
+ },
+ "category_lvl3":{
+ "id":"13",
+ "qty":"28"
+ },
+ "category_node":{
+ "root_id":"1",
+ "parent_id":"6",
+ "children_id":"5"
+ },
+ "category_tree_branches_qty":"6",
+ "abstract_sku_highest_rating":"035"
+ },
+ "products":{
+ "bundle_product":{
+ "abstract_sku":"211",
+ "concrete_sku":"211_123",
+ "product_name":"HP Bundle"
+ },
+ "bundled":{
+ "product_1":{
+ "abstract_sku":"150",
+ "concrete_sku":"150_29554292",
+ "concrete_name":"HP Chromebook 11"
+ },
+ "product_2":{
+ "abstract_sku":"127",
+ "concrete_sku":"127_22828284",
+ "concrete_name":"HP Z 620"
+ },
+ "product_3":{
+ "abstract_sku":"121",
+ "concrete_sku":"121_29406823",
+ "concrete_name":"HP 200 280 G1"
+ }
+ },
+ "products_in_bundle":{
+ "total_qty_of_products":"3",
+ "qty_of_each_product":"1"
+ },
+ "configurable_bundle":{
+ "slot_1":{
+ "product_1":"003_26138343",
+ "product_no_stock":"011_30775359"
+
+ },
+ "slot_5":{
+ "product_1":"005_30663301",
+ "product_2":"008_30692992"
+ },
+ "slot_6":{
+ "product_1":"201_11217755"
+ }
+ },
+ "special_product_abstract_sku":{
+ "with_multivariant":"M58035",
+ "with_measurement_unit":"M23723",
+ "with_packaging_unit":"M21766"
+ },
+ "product_related_product_with_related_relation":{
+ "sku":"058",
+ "name":"Acer Liquid Jade"
+ },
+ "product_with_relations":{
+ "has_related_products":{
+ "sku":"204"
+ },
+ "has_alternative_products":{
+ "sku":"M21100"
+ },
+ "has_upselling_products":{
+ "sku":"063",
+ "concrete_sku":"063_29231675"
+ }
+ },
+ "concrete_of_alternative_product_with_relations_upselling":{
+ "sku":"007_30691822"
+ },
+ "product_related_product_with_upselling_relation":{
+ "sku":"051",
+ "name":"Samsung Galaxy S6 edge"
+ },
+ "concrete_of_product_without_relations":{
+ "sku":"019_21081473"
+ },
+ "concrete_product_with_abstract_product_alternative":{
+ "sku":"138_30046855",
+ "name":"Acer TravelMate P258-M",
+ "name_in_lower_case":"acer travelmate p258-m"
+ },
+ "concrete_product_with_concrete_product_alternative":{
+ "sku":"155_30149933",
+ "name":"Lenovo IdeaPad Yoga 500",
+ "name_in_lower_case":"lenovo ideapad yoga 500",
+ "promotional_items_sku":"112",
+ "promotional_items_sku1":"68"
+ },
+ "abstract_product_with_alternative":{
+ "sku":"155",
+ "name":"Lenovo IdeaPad Yoga 500"
+ },
+ "alternative_abstract_product":{
+ "sku":"134",
+ "price_chf":"11345"
+ },
+ "abstract_available_product_with_stock":{
+ "sku":"183",
+ "price_de":"38168",
+ "price_at":"38168",
+ "name":"Sony Xperia SGP512E1",
+ "description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos, videos and work-related files with you wherever you need to go. The Galaxy Tab S2’s 4:3 ratio display is optimised for magazine reading and web use. Switch to Reading Mode to adjust screen brightness and change wallpaper - create an ideal eBook reading environment designed to reduce the strain on your eyes. Get greater security with convenient and accurate fingerprint functionality. Activate fingerprint lock by pressing the home button. Use fingerprint verification to restrict / allow access to your web browser, screen lock mode and your Samsung account. ",
+ "superattribute":"color"
+ },
+ "concrete_available_product":{
+ "sku":"183_21811723",
+ "meta_keywords":"Sony,Communication Electronics",
+ "meta_description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos,",
+ "label":"204_29851280",
+ "with_stock_one_concrete_with_superattribute":{
+ "sku":"156",
+ "name":"Acer Iconia B1-850",
+ "description":"Portable charm With a bevy of trendy, eye catching colours to suit any lifestyle and show your personality, this slim and lightweight tablet designed to be travel friendly. Plus its beautifully textured anti-slip finish helps you keep a firm grip wherever you go. Looks sharp and stays sharp. The HD LCD with IPS1 technology brings out every detail of the display from any angle. Put that together with Zero Air Gap technology and you get brighter and crisper images with higher contrast and considerably better visibility in sunlight. A highly effective anti-fingerprint coating reduces messy fingerprints and smudges, and makes the screen much easier to clean. Add to that Acer’s innovative Touch WakeApp which adds new one-touch gestures to both wake the tablet up and pop it right into whatever app you want instant access to.",
+ "superattribute_name":"form_factor"
+ },
+ "with_superattribute":{
+ "sku":"156_32018944",
+ "meta_keywords":"Acer,Communication Electronics",
+ "meta_description":"Portable charm With a bevy of trendy, eye catching colours to suit any lifestyle and show your personality, this slim and lightweight tablet designed to be"
+ }
+ },
+ "warehouse_user":{
+ "name":"",
+ "password":""
+ },
+ "admin_not_warehouse_user":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "product_availability":{
+ "concrete_available_with_stock_and_never_out_of_stock_sku":"005_30663301",
+ "concrete_available_with_stock_and_never_out_of_stock_sku1":"004_30663302",
+ "concrete_available_with_stock_and_never_out_of_stock_name":"Canon IXUS 175",
+ "abstract_available_product_with_no_stock_and_never_out_of_stock":"154",
+ "abstract_available_with_stock_and_never_out_of_stock":"209",
+ "abstract_unavailable_product":"011",
+ "concrete_available_product_with_stock":"001_25904006",
+ "concrete_available_product_with_stock2":"174_27253016",
+ "concrete_available_product_without_stock":"031_30021637"
+ },
+ "abstract_product":{
+ "volume_prices":{
+ "sku":"193",
+ "name":"TomTom Golf"
+ },
+ "original_prices":{
+ "sku":"072"
+ },
+ "label":{
+ "sku":"145",
+ "name":"DELL Chromebook 13"
+ },
+ "with_reviews":{
+ "sku":"035",
+ "name":"Canon PowerShot N"
+ },
+ "with_options":{
+ "sku":"012",
+ "name":"Canon IXUS 165"
+ },
+ "product_in_different_locales":{
+ "sku":"001",
+ "name":"Canon IXUS 160",
+ "description_de":"Beeindruckende Aufnahmen",
+ "description_en":"Add a personal touch"
+ }
+ },
+ "concrete_product":{
+ "original_prices":{
+ "sku":"072_21927455",
+ "name":"Samsung Galaxy Note 3"
+ },
+ "volume_prices":{
+ "sku":"193_32124735"
+ },
+ "volume_prices_net":{
+ "amount":"15000"
+ },
+ "volume_prices_gross":{
+ "amount":"16500"
+ },
+ "with_review":{
+ "sku":"086_30521602",
+ "name":"Samsung Gear S2"
+ },
+ "with_options":{
+ "sku":"012_25904598",
+ "name":"Canon IXUS 165"
+ },
+ "threshold_limit":{
+ "sku":"006_30692993"
+ },
+ "one_image_set":{
+ "sku":"666_133",
+ "name":"Gift Card 5000"
+ },
+ "multiple_image_set":{
+ "sku":"158_29885222",
+ "set_name":"Asus ZenPad Z170C"
+ }
+ },
+ "multivariant":{
+ "abstract_product":{
+ "concretes_3":"127",
+ "concretes_name_3":"HP Z 620",
+ "concretes_superattribute_3":"total_storage_capacity",
+ "sku":"130"
+ },
+ "concrete_product":{
+ "sku_variant1":"130_29285281",
+ "sku_variant2":"130_24326086"
+ }
+ },
+ "product":{
+ "option_1":"OP_2_year_waranty",
+ "option_1_name":"Two (2) year limited warranty",
+ "option_2":"OP_insurance",
+ "option_group_name":"Three (3) year limited warranty"
+ },
+ "review":{
+ "title":"This is a review",
+ "text":"This is review text",
+ "default_rating":"5"
+ },
+ "configurable_product":{
+ "sku_1": "124_29866591",
+ "sku_2": "124_31623088",
+ "name":"HP ProDesk 400 G3"
+ }
+ },
+ "product_attributes":{
+ "brand_1":"Soennecken",
+ "brand_2":"edding",
+ "brand_3":"Mauser",
+ "brand_4":"Sony",
+ "brand_5":"Lenovo",
+ "brand_6":"Acer",
+ "material_1":"aluminum",
+ "material_2":"metal",
+ "material_3":"chipboard",
+ "material_4":"Steel sheets, stove-enameled",
+ "internal_memory":"3 GB",
+ "aspect_ratio":"16:10",
+ "storage_media":"flash",
+ "display_technology":"TFT",
+ "delivery_1":"assembled",
+ "price_unit_1":"piece",
+ "color_5":"white",
+ "color_4":"black",
+ "color_3":"purple",
+ "color_1":"yellow",
+ "color_2":"blue",
+ "processor_frequency":"1.3 GHz",
+ "internal_storage_capacity":"16 GB",
+ "processor_cores":"4",
+ "product_management":{
+ "superattribute_id":"4g",
+ "attribute_free_input_id":"4g_standards",
+ "attribute_no_input_id":"bundled_product"
+ }
+ },
+ "content":{
+ "abstract_list":{
+ "product_id":"apl-watches",
+ "product1_sku":"083",
+ "product1_name":"Samsung Gear 2 Classic",
+ "product2_sku":"087",
+ "product2_name":"Samsung Gear S2",
+ "size":"4"
+ },
+ "banner_1":{
+ "id":"br-smartwatches",
+ "name":"The freedom of cellular"
+ },
+ "cms_pages":{
+ "qty":"5",
+ "first_cms_page":{
+ "name":"Imprint",
+ "name_in_lower_case":"imprint",
+ "url_en":"/en/imprint"
+ },
+ "second_cms_page":{
+ "name":"Dolor sit amet",
+ "name_in_lower_case":"dolor sit amet",
+ "url_en":"/en/dolor"
+ },
+ "third_cms_page":{
+ "name":"Data Privacy",
+ "name_in_lower_case":"data privacy",
+ "url_en":"/en/privacy"
+ },
+ "cms_page_with_product_lists":{
+ "id":"10014bd9-4bba-5a54-b84f-31b4b7efd064",
+ "name":"Demo Landing Page",
+ "url":"/en/demo-landing-page"
+ }
+ },
+ "category_collection_name":"Digital Cameras",
+ "category_collection_url":"/en/cameras-&-camcorders/digital-cameras",
+ "category_nodes_storage_name":"Cameras & Camcorders",
+ "category_nodes_storage_url":"/en/cameras-&-camcorders",
+ "subcategory_nodes_storage_name":"Digital Cameras",
+ "subcategory_nodes_storage_url":"/en/cameras-&-camcorders/digital-cameras",
+ "cms_page_collection_name":"GTC",
+ "cms_page_collection_url":"/en/gtc",
+ "brand_name":"canon"
+ },
+ "cart":{
+ "x_anonymous_prefix":"anonymous"
+ },
+ "availability":{
+ "stock_is_0":"0.0000000000",
+ "stock_is_20":"20.0000000000"
+ },
+ "misc":{
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "test_cart_name":"Test-cart",
+ "qty_of_categories_in_category_trees":"6",
+ "qty_of_subcategories_in_category_trees":"2",
+ "tax_rate":"19.00",
+ "tax_rate1":"19",
+ "color_name":"black",
+ "payment":{
+ "provider_name":"DummyPayment",
+ "method_name":"Invoice"
+ },
+ "shipment":{
+ "carrier_name":"DHL",
+ "method_name":"Standard",
+ "method_name_2":"Express",
+ "method_name_5":"Next Day",
+ "delivery_date":"2030-12-31"
+ },
+ "discount":{
+ "discount_1":{
+ "name":"Free standard delivery",
+ "description":"Free standard delivery for all orders above certain value depending on the currency",
+ "total_sum":"490"
+ },
+ "discount_2":{
+ "name":"5% off white"
+ },
+ "discount_3":{
+ "id":"3"
+ },
+ "concrete":{
+ "product_1":{
+ "sku":"108298",
+ "name":"Mauser hinged door cabinet - sideboard, 4 compartments, center separating wall - HxWxD 1225 x 1600 x 420 mm - light gray / ultramarine blue",
+ "total_sum_of_discounts":"14840"
+ },
+ "product_2":{
+ "sku":"213216",
+ "name":"office akktiv base cabinet - HxWxD 942 x 913 x 420 mm - light gray, RAL 7035",
+ "total_sum_of_discounts":"8096"
+ },
+ "product_3":{
+ "sku":"401768",
+ "name":"EUROKRAFT aluminum hand truck - Load capacity 200 kg, with skids - load capacity 200 kg"
+ },
+ "product_with_voucher_code":{
+ "sku":"058_24245592"
+ }
+ },
+ "amount":{
+ "product_2":{
+ "20%_off_storage":"5783",
+ "10%_off_minimum_order":"2313"
+ },
+ "product_3":{
+ "20%_off_storage":"16383",
+ "10%_discount":"1882"
+ },
+ "product_1":{
+ "20%_off_storage":"10600",
+ "10%_off_minimum_order":"4240"
+ }
+ }
+ }
+ },
+ "url_resolver":{
+ "url_resolver_abstract_product":"/en/canon-ixus-160-1",
+ "url_resolver_product_entity":"abstract-products",
+ "url_resolver_product_id":"001",
+ "url_resolver_category_nodes":"/en/computers",
+ "url_resolver_category_nodes_entity":"category-nodes",
+ "url_resolver_category_nodes_id":"5",
+ "url_resolver_cms":"/en/privacy",
+ "url_resolver_cms_entity":"cms-pages",
+ "url_resolver_cms_id":"1e9fb640-9073-55f4-a2d2-535090c92025"
+ },
+ "return_reason":{
+ "return_reasons_qty":"3",
+ "return_reason_damaged":"Damaged"
+ },
+ "wishlists":{
+ "wishlist_name":"HS"
+ },
+ "configurable_bundles":{
+ "configurable_bundle_template_1_uuid":"8d8510d8-59fe-5289-8a65-19f0c35a0089",
+ "configurable_bundle_first_slot_item_sku":"001_25904006",
+ "configurable_bundle_first_slot_item_sku2":"002_25904004",
+ "configurable_bundle_slot_1_uuid":"332b40ac-a789-57ce-bec0-23d8dddd71eb",
+ "configurable_bundle_template_2_uuid":"c8291fd3-c6ca-5b8f-8ff5-eccd6cb787de",
+ "configurable_bundle_slot_5_uuid":"9626de80-6caa-57a9-a683-2846ec5b6914",
+ "configurable_bundle_slot_6_uuid":"2a5e55b1-993a-5510-864c-a4a18558aa75",
+ "configurable_bundle_template_name_1":"All in",
+ "configured_bundle_quantity":2
+ },
+ "productConfigurationInstance": {
+ "productConfigurationInstance":{
+ "displayData": "{\"Preferred time of the day\": \"Afternoon\", \"Date\": \"9.09.2050\"}",
+ "configuration": "{\"time_of_day\": \"3\"}",
+ "configuratorKey": "DATE_TIME_CONFIGURATOR",
+ "isComplete": true
+ }
+ },
+ "dataType":{
+ "array":[]
+ },
+ "dummy_api_key":"eba8110c9f9bf5685e8b5f4eba9b17c2",
+ "dummy_key_hash":"f683f48de788d57cd396fc212ef33fd146e1ff0b51cde37ecb4ddd77eeed1706",
+
+ "servicePoints": {
+ "servicePoints":[
+ {
+ "uuid":"test-service-point",
+ "name":"TSP",
+ "key":"tsp"
+ },
+ {
+ "uuid":"test-service-point-2",
+ "name":"TSP2",
+ "key":"tsp2"
+ }
+ ],
+ "servicePointAddresses":[
+ {
+ "uuid":"test-service-point-address",
+ "address1":"Test address",
+ "address2":"Test address 2",
+ "address3":"Test address 3",
+ "city":"City",
+ "zipCode":"10115"
+ }
+ ],
+ "services":[
+ {
+ "uuid":"test-service",
+ "key":"ts"
+ }
+ ],
+ "serviceTypes":[
+ {
+ "uuid":"test-service-type",
+ "name":"Test service type",
+ "key":"tst"
+ }
+ ]
+ },
+ "warehouses":{
+ "warehouses":
+ {
+ "uuid": "test-warehouse",
+ "is_active": true,
+ "name": "Test warehouse"
+ }
+
+ },
+ "push_notifications": {
+ "push_notification_subscriptions": [
+ {
+ "providerName": "web-push-php",
+ "group": {
+ "name": "warehouse",
+ "identifier": ""
+ },
+ "payload": {
+ "endpoint": "endpoint",
+ "publicKey": "publicKey",
+ "authToken": "authToken"
+ },
+ "localeName": ""
+ }
+ ]
+ },
+ "push_notification_providers":{
+ "push_notification_provider_uuid":"2a304ddf-d51b-514f-bd11-6e818a27fe23"
+ },
+ "shipment_type":{
+ "shipment_type_uuid":"174d9dc0-55ae-5c4b-a2f2-a419027029ef",
+ "shipment_type_name":"Pickup"
+ },
+ "warehouse_user_assignment":{
+ "user_uuid":"48a6c610-693e-5d88-bdce-3c6018b3abd2",
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f",
+ "user_uuid_2":"92cd431f-96e3-5259-91cb-ab9f6d14829f",
+ "user_uuid_3":"8565d483-70cd-5c73-bc6a-96d2e70ddee1",
+ "user_name":"martha@video-king.nl",
+ "user_first_name":"Martha",
+ "user_last_name":"Farmer",
+ "user_name_1":"admin@spryker.com",
+ "user_first_name_1":"Admin",
+ "user_last_name_1":"Spryker"
+ },
+ "warehouse": {
+ "warehouse_uuid": "8e5f7bf2-ab97-595c-9b42-487392e2af9b",
+ "warehouse_uuid_budget_cameras": "86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "warehouse_name": "Spryker MER000001 Warehouse 1",
+ "warehouse_name_budget_cameras": "Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid": "86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "video_king_warehouse_name": "Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker": "4"
+ },
+ "demo_service_point": {
+ "spryker_main_store": {
+ "uuid": "262feb9d-33a7-5c55-9b04-45b1fd22067e",
+ "uuid2": "7e3b03e0-c53c-5298-9ece-968f4628b4f8",
+ "name": "Spryker Main Store",
+ "key": "sp1"
+ },
+ "service_point_address": {
+ "uuid": "74768ee9-e7dd-5e3c-bafd-b654e7946c54",
+ "uuid2": "7a711afc-02ce-5f54-a08c-fadfaf5713c6",
+ "address1": "Julie-Wolfthorn-Straße",
+ "address2": "1",
+ "address3": "None",
+ "city": "Berlin",
+ "zip": "10115"
+ }
+ }
+}
diff --git a/atest/testdata/performance/resources/environments/environments_api_mp_b2b.json b/atest/testdata/performance/resources/environments/environments_api_mp_b2b.json
new file mode 100644
index 0000000..006ec0e
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_api_mp_b2b.json
@@ -0,0 +1,844 @@
+{
+ "environment":"api_mp_b2b",
+ "env":{
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "dataType": {
+ "array": []
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user":{
+ "email":"sonia@spryker.com",
+ "first_name":"Sonia",
+ "last_name":"Wagner",
+ "password":"change123",
+ "password_new":"qweRTY_123456",
+ "password_new_additional":"Change!23456",
+ "reference":"DE--21",
+ "salutation":"Ms"
+ },
+ "yves_second_user":{
+ "email":"bill.martin@spryker.com",
+ "first_name":"Martin",
+ "last_name":"Bill",
+ "password":"change123",
+ "reference":"DE--4",
+ "salutation":"Mr"
+ },
+ "yves_third_user":{
+ "email":"maxmusterman@spryker.com",
+ "first_name":"Max",
+ "last_name":"Musterman",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "salutation":"Mr"
+ },
+ "yves_fourth_user":{
+ "email":"Lilu@ottom.de",
+ "first_name":"Lilu",
+ "last_name":"Dallas",
+ "password":"change123",
+ "reference":"DE-30",
+ "salutation":"Ms"
+ },
+ "yves_eighth_user":{
+ "email":"maria.williams@spryker.com",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "password_new_additional":"qweRTY_123456",
+ "reference":"DE--2"
+ },
+ "yves_ninth_user":{
+ "email":"maggie.may@spryker.com",
+ "first_name":"Maggie",
+ "last_name":"May",
+ "password":"Change!23456",
+ "password_new":"qweRTY_123456",
+ "reference":"DE--3",
+ "salutation":"Ms"
+ },
+ "yves_ottom_admin_user":{
+ "email":"andrew@ottom.de",
+ "first_name":"Andrew",
+ "last_name":"Wedner",
+ "password":"change123",
+ "reference":"DE-8",
+ "salutation":"Mr"
+ },
+ "yves_shared_shopping_list_user":{
+ "email":"Trever.m@spryker.com",
+ "first_name":"Trever",
+ "last_name":"Meier",
+ "password":"change123",
+ "salutation":"Mr"
+ },
+ "yves_shared_shopping_cart_user":{
+ "email":"Solomon@spryker.com",
+ "first_name":"Solomon",
+ "last_name":"Wesner",
+ "password":"change123",
+ "salutation":"Mr"
+ },
+ "gender":{
+ "female":"Female",
+ "male":"Male"
+ },
+ "email":{
+ "name":"sonia",
+ "domain":"@spryker.com"
+ },
+ "zed_admin":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "agent":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "non_agent":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "customer_reference":{
+ "de_1":"DE--1",
+ "de_10":"DE--10",
+ "de_15":"DE--15",
+ "de_34":"DE--34",
+ "de_44":"DE--44"
+ },
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ }
+ },
+ "address":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"false",
+ "billing_status":"false"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ }
+ },
+ "store":{
+ "de":"DE",
+ "us":"US"
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ }
+ },
+ "shopping-list":{
+ "shopping_list_name":"My Shopping List",
+ "1st_shopping_list":{
+ "id":"cf032865-d1ad-5e27-803a-423bd15ced66",
+ "name":"Newcomers"
+ },
+ "2nd_shopping_list":{
+ "name":"Weekly office"
+ },
+ "3rd_shopping_list":{
+ "name":"Monthly office"
+ }
+ },
+ "search":{
+ "total_number_of_products_in_search":"414",
+ "ipp":{
+ "default":"12",
+ "middle":"24",
+ "biggest":"36"
+ },
+ "default_qty":{
+ "ipp_pages":"35",
+ "categories":"33",
+ "colors":"10",
+ "labels":"5",
+ "materials":"10",
+ "brands":"10",
+ "sorting_options":"5",
+ "product_classes":"0"
+ },
+ "default_rating":{
+ "min":"4",
+ "max":"5"
+ },
+ "label":{
+ "new":"New",
+ "sale":"SALE %",
+ "manual":"Top",
+ "discontinued":"Discontinued",
+ "alternatives":"Alternatives available"
+ },
+ "category_lvl1":{
+ "id":"11",
+ "qty":"172"
+ },
+ "category_lvl2":{
+ "id":"12",
+ "qty":"56"
+ },
+ "category_lvl3":{
+ "id":"13",
+ "qty":"28"
+ },
+ "category_tree_branches_qty":"6",
+ "abstract_sku_highest_rating":"M1016129"
+ },
+ "products":{
+ "bundle_product":{
+ "abstract":{
+ "sku":"M90851",
+ "name":"IDEAL document shredder - Power 1300 watts, 165 l volume",
+ "product_1_sku":"M23457",
+ "product_2_sku":"C2235",
+ "product_3_sku":"M11542"
+ },
+ "concrete":{
+ "sku":"000201",
+ "name":"IDEAL document shredder - Power 1300 watts, 165 l volume - 23 – 25 sheets, safety level P-4, particle",
+ "product_1_sku":"424453",
+ "product_1_name":"Schneider ballpoint pen HAPTIFY 135323 M 0.5 mm, dark blue/light blue",
+ "product_2_sku":"1001454",
+ "product_2_name":"Schomburg standing desk - HxWxD 1094 x 600 x 500 mm, beech",
+ "product_3_sku":"104517",
+ "product_3_name":"Wood stackable chair - 4-foot substructure, upholstered seat - Cover anthracite, substructure coated"
+ },
+ "products_in_bundle":{
+ "total_qty_of_products":"3",
+ "qty_of_each_product":"1"
+ }
+ },
+ "special_product_abstract_sku":{
+ "with_multivariant":"M58035",
+ "with_measurement_unit":"M23723",
+ "with_packaging_unit":"M21766"
+ },
+ "product_with_relations":{
+ "has_related_products":{
+ "abstract_sku":"M29529",
+ "concrete_sku":"419872"
+ },
+ "has_alternative_products":{
+ "abstract_sku":"M21100"
+ },
+ "has_upselling_products":{
+ "abstract_sku":"M29502",
+ "concrete_sku":"419880"
+ }
+ },
+ "product_with_related_relations":{
+ "has_upselling_products":{
+ "sku":"M29499",
+ "name":"Safescan counterfeit test device - SAFESCAN 45 UV"
+ },
+ "has_related_products":{
+ "sku":"M29501",
+ "name":"Safescan automatic banknote counter - UV counterfeit recognition"
+ }
+ },
+ "discount":{
+ "id_3":{
+ "name":"5% off white",
+ "description":"Get a 5% discount on all white products with voucher code"
+ },
+ "id_4":{
+ "name":"10% off Safescan",
+ "description":"Get a 10% discount on all Safescan brand products with voucher code"
+ },
+ "concrete_products_with_discounts":{
+ "concrete_product_with_brand_safescan":"419872",
+ "concrete_product_with_brand_safescan_and_white_color":"419901"
+ },
+ "products_cost_with_discounts":{
+ "voucher_concrete_product_1_with_brand_safescan_2_items":"782",
+ "voucher_concrete_product_with_brand_safescan_and_white_color_2_items":"3201"
+ },
+ "cart_rule_name_10_off_minimum_order":"10% off minimum order"
+ },
+ "concrete_of_product_with_relations_upselling":{
+ "product_options":{
+ "OP_1":{
+ "id":"OP_1_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_1_year_waranty",
+ "option_name":"One (1) year limited warranty"
+ },
+ "OP_2":{
+ "id":"OP_2_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_2_year_waranty",
+ "option_name":"Two (2) year limited warranty"
+ },
+ "OP_3":{
+ "id":"OP_3_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_3_year_waranty",
+ "option_name":"Three (3) year limited warranty"
+ },
+ "OP_insurance":{
+ "id":"OP_insurance",
+ "option_group_name":"Two (2) year insurance coverage",
+ "sku":"OP_insurance",
+ "option_name":"Two (2) year insurance coverage"
+ }
+ },
+ "product_reviews":{
+ "review_1":{
+ "id":"1",
+ "rating":"1",
+ "nickname":"Spencor",
+ "summary":"To heavy, uncomfortable",
+ "description":"YOu really feel there is tech on your wrist with this watch, it felt like a weight on my wrist and strap was very uncomfortable. Battery dies really fast."
+ },
+ "review_2":{
+ "id":"2",
+ "rating":"4",
+ "nickname":"Bill",
+ "summary":"My boss loved it",
+ "description":"Snazzy design and exactly what my kid wanted."
+ },
+ "review_3":{
+ "id":"3",
+ "rating":"4",
+ "nickname":"Maggie",
+ "summary":"Great product.",
+ "description":"I absolutely love it but why doesnt it have a built in speaker? Had it for 2 months now, worn it every day and it's been very durable and responsive."
+ },
+ "review_4":{
+ "id":"4",
+ "rating":"5",
+ "nickname":"Maria",
+ "summary":"Easy to set up and use! ",
+ "description":"Received this as a Birthday present. I love my GearS2!!"
+ },
+ "review_5":{
+ "id":"5",
+ "rating":"5",
+ "nickname":"Spencor",
+ "summary":"Five Stars",
+ "description":"Daughter is very happy with her new phone!"
+ },
+ "review_6":{
+ "id":"6",
+ "rating":"3",
+ "nickname":"Maria",
+ "summary":"Good for the price",
+ "description":"I bought the phone a year ago, I could complain but what would be the point in that."
+ },
+ "review_7":{
+ "id":"7",
+ "rating":"4",
+ "nickname":"Maggie",
+ "summary":"Great but not amazing",
+ "description":"I guess this is waht you get when you compromise. I wanted something I could use with one hand and mount on my belt. But the performance is crappyer than my old phone and so it the call clarity and speed. I was going to go for the Samsung A3 2017 but the specs are not much better and it is way bigger."
+ },
+ "review_8":{
+ "id":"8",
+ "rating":"4",
+ "nickname":"Bill",
+ "summary":"Works ok",
+ "description":"We used to have an S3 mini. We were expecting a phone about the same size or maybe a little bigger than thre S3 mini, however,to our surprise it is almost as big as an S4. Whats the deal with that?"
+ },
+ "review_9":{
+ "id":"9",
+ "rating":"4",
+ "nickname":"Spensor",
+ "summary":"Like it",
+ "description":"Accidently dropped it in the toilet and it worked fine afterwards."
+ }
+ },
+ "category_nodes":{
+ "category_node_23":{
+ "id":"23",
+ "name":"Office equipment"
+ },
+ "category_node_25":{
+ "id":"25",
+ "name":"Money Counters and Validators"
+ }
+ }
+ },
+ "product_related_product_with_upselling_relation":{
+ "sku":"M29499",
+ "merchant_reference":"MER000008",
+ "name":"Safescan counterfeit test device - SAFESCAN 45 UV",
+ "description":" Counterfeit test device, SAFESCAN 45 UV, doubled UV lamp. Strong, doubled UV lamp (2 x 6 W). Monitors the UV features of banknotes. Suitable for all currencies. Suitable for all driver’s licenses and documents. Suitable for identity cards and credit cards. CE-certified. ",
+ "concrete_available_product":{
+ "sku":"419869",
+ "name":"Safescan Counterfeit test device, SAFESCAN 45 UV, doubled UV lamp",
+ "description":"Counterfeit test device, SAFESCAN 45 UV, doubled UV lamp. Strong, doubled UV lamp (2 x 6 W). Monitors the UV features of banknotes. Suitable for all currencies. Suitable for all driver’s licenses and documents. Suitable for identity cards and credit cards. CE-certified.",
+ "meta_title":"",
+ "meta_keywords":"Geldscheinprüfer,Geldprüfer",
+ "meta_description":" Falschgeld-Prüfgerät, SAFESCAN 45 UV, doppelte UV Lampe. Starke, doppelte UV Lampe (2 x 6 W). Kontrolliert die UV-Merkmale von Geldscheinen. Eignet sich für alle Währungen. Eignet sich für alle Führerscheine und Dokumente. Eignet sich für Identitätskarten und Kreditkarten. CE-zertifiziert. "
+ }
+ },
+ "concrete_product_with_alternative":{
+ "sku":"420566",
+ "name":"Verbatim USB stick Store n Go V3 49173 32GB USB3.0 gray",
+ "name_lower_case":"verbatim usb stick store n go v3 49173 32gb usb3.0 gray",
+ "abstract_sku":"M90810"
+ },
+ "concrete_product_with_discontinued":{
+ "sku":"421540"
+ },
+ "abstract_product_with_alternative":{
+ "sku":"M21100",
+ "name":"Verbatim USB stick Store n Go V3 49173 32GB USB3.0 gray"
+ },
+ "alternative_abstract_product":{
+ "sku":"M21099",
+ "price_chf":"1130"
+ },
+ "abstract_available_product_with_stock":{
+ "sku":"M61125",
+ "price_de":"21759",
+ "price_at":"21859",
+ "merchant_reference":"MER000008",
+ "name":"Prosedia vertebral disc swivel chair with synchronous mechanics and contoured seat - backrest height 660 mm",
+ "description":" Easy-to-care-for fabric cover. Substructure in graphite black RAL 9011.
Standard rolling for soft floors.
The backrest has height-adjustable lumbar support. ",
+ "superattribute":"bezugsfarbe",
+ "meta_title":"Prosedia vertebral disc swivel chair with synchronous mechanics and contoured seat - backrest height 660 mm",
+ "meta_keywords":"Arbeitsdrehstuhl,Bandscheibendrehstuhl,Bandschreibendrehstuhl,Bürodrehstuhl,Bürostuhl,Drehstuhl,Schreibtischstuhl,Universalstuhl",
+ "meta_description":" Pflegeleichter Stoffbezug. Gestell in Graphitschwarz RAL 9011.
Standardmäßig Rollen für weiche Böden.
Die Rückenlehne verfügt über eine höhenverstellbare Lendenwirbelstütze. ",
+ "concrete_available_product":{
+ "sku":"102712",
+ "name":"Prosedia vertebral disc swivel chair with synchronous mechanics and contoured seat - backrest height 660 mm - cover color orange",
+ "description":"Easy-to-care-for fabric cover. Substructure in graphite black RAL 9011.
Standard rolling for soft floors.
The backrest has height-adjustable lumbar support.",
+ "meta_title":"Prosedia vertebral disc swivel chair with synchronous mechanics and contoured seat - backrest height 660 mm",
+ "meta_keywords":"Arbeitsdrehstuhl,Bandscheibendrehstuhl,Bandschreibendrehstuhl,Bürodrehstuhl,Bürostuhl,Drehstuhl,Schreibtischstuhl,Universalstuhl",
+ "meta_description":" Pflegeleichter Stoffbezug. Gestell in Graphitschwarz RAL 9011.
Standardmäßig Rollen für weiche Böden.
Die Rückenlehne verfügt über eine höhenverstellbare Lendenwirbelstütze. "
+ },
+ "category_nodes":{
+ "category_node_14":{
+ "id":"14",
+ "name":"Swivel Chairs"
+ },
+ "category_node_11":{
+ "id":"11",
+ "name":"Office furniture"
+ },
+ "category_node_12":{
+ "id":"12",
+ "name":"Chairs"
+ }
+ },
+ "product_options":{
+ "OP_1":{
+ "id":"OP_1_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_1_year_waranty",
+ "option_name":"One (1) year limited warranty"
+ },
+ "OP_2":{
+ "id":"OP_2_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_2_year_waranty",
+ "option_name":"Two (2) year limited warranty"
+ },
+ "OP_3":{
+ "id":"OP_3_year_waranty",
+ "option_group_name":"Three (3) year limited warranty",
+ "sku":"OP_3_year_waranty",
+ "option_name":"Three (3) year limited warranty"
+ },
+ "OP_insurance":{
+ "id":"OP_insurance",
+ "option_group_name":"Two (2) year insurance coverage",
+ "sku":"OP_insurance",
+ "option_name":"Two (2) year insurance coverage"
+ }
+ }
+ },
+ "abstract_product":{
+ "product_with_volume_prices":{
+ "abstract_sku":"M21189",
+ "abstract_name":"Post-it stick note Super Sticky Meeting Notes 6445-4SS 4 pieces/pack",
+ "concrete_sku":"420685"
+ },
+ "product_with_original_prices":{
+ "abstract_sku":"M74972",
+ "concrete_sku":"101863",
+ "concrete_name":"HSM SECURIO document shredder - for multi-person office, 34 l - stripes, 19 – 21 sheets"
+ },
+ "abstract_product_with_label":{
+ "sku":"M21691",
+ "name":"Clairefontaine Collegeblock 8272C DIN A5, 90 sheets"
+ },
+ "product_with_reviews":{
+ "sku":"M719",
+ "name":"Rectangular table, rectangular tubing - 1600 x 800 mm",
+ "qty":"4"
+ },
+ "product_with_options":{
+ "abstract_sku":"M29501",
+ "abstract_ame":"Safescan automatic banknote counter - UV counterfeit recognition",
+ "concrete_sku":"419871",
+ "concrete_name":"Safescan automatic banknote counter, UV Counterfeit recognition, SAFESCAN 2210"
+ },
+ "product_availability":{
+ "abstract_available_with_stock_and_never_out_of_stock":"M87",
+ "concrete_available_with_stock_and_never_out_of_stock":"657716",
+ "concrete_available_with_stock_and_never_out_of_stock_name":"FRIWA stackable chair - with closed back",
+ "abstract_available_product_with_no_stock_and_never_out_of_stock":"M90851",
+ "abstract_unavailable_product":"M22432",
+ "concrete_unavailable_product":"212447",
+ "product_2":{
+ "abstract_available_with_stock_and_never_out_of_stock":"M24632",
+ "concrete_available_with_stock_and_never_out_of_stock":"426615"
+ },
+ "product_3":{
+ "abstract_available_with_stock_and_never_out_of_stock":"M87416"
+ }
+ },
+ "abstract_product_with_variants":{
+ "concretes_3":"M29456",
+ "concretes_name_3":"Gmöhling aluminum data removal container - Exterior - LxWxH 435 x 385 x 650 mm",
+ "concretes_superattribute_3":"material"
+ },
+ "product_in_different_locales":{
+ "sku":"M29455",
+ "description_de":"Alu-Datenentsorgungsbehälter",
+ "description_en":"Aluminum data disposal container"
+ }
+ },
+ "concrete_available_product_with_stock":"420566",
+ "concrete_available_product_without_stock":"422780",
+ "concrete_product_with_promotions":"212427",
+ "concrete_product_with_threshold_limit":"424273",
+ "concrete_product":{
+ "image_set":{
+ "one":{
+ "sku":"401768",
+ "name":"EUROKRAFT aluminum hand truck - Load capacity 200 kg, with skids - load capacity 200 kg"
+ },
+ "multiple":{
+ "sku":"212427",
+ "name":"Wood stackable chair, upholstered - VE 4 pieces, substructure chromed - upholstery black"
+ }
+ }
+ },
+ "packaging_unit":{
+ "m":"METR",
+ "i":"ITEM",
+ "cm":"CMET",
+ "m_name":"Meter"
+ },
+ "concrete_product_random_weight":{
+ "qty_of_units":"1",
+ "amount":"5.0000000000",
+ "conversion":"1",
+ "precision":"100",
+ "packaging_unit":"19",
+ "sku":"421519_3",
+ "name":"Box Papermate Kugelschreiber InkJoy 700 RT S0957340 M Druckmechanik schwarz",
+ "measurement_unit":"19"
+ },
+ "measurement_unit_m":"METR",
+ "product_options":{
+ "option_1":"OP_2_year_waranty",
+ "option_1_name":"Two (2) year limited warranty",
+ "option_2":"OP_insurance"
+ },
+ "discount_concrete_product":{
+ "discount_concrete_product_sku":"103117",
+ "product_1":{
+ "sku":"108298",
+ "name":"Mauser hinged door cabinet - sideboard, 4 compartments, center separating wall - HxWxD 1225 x 1600 x 420 mm - light gray / ultramarine blue",
+ "discount_amount_with_20_percentage_off_storage":"10600",
+ "discount_amount_with_10_percentage_off_minimum_order":"4240",
+ "discount_amount_total_sum_of_discounts":"14840"
+ },
+ "product_2":{
+ "sku":"213216",
+ "name":"office akktiv base cabinet - HxWxD 942 x 913 x 420 mm - light gray, RAL 7035",
+ "discount_amount_with_20_percentage_off_storage":"5783",
+ "discount_amount_with_10_percentage_off_minimum_order":"2313",
+ "discount_amount_total_sum_of_discounts":"8096"
+ },
+ "product_3":{
+ "sku":"401768",
+ "name":"EUROKRAFT aluminum hand truck - Load capacity 200 kg, with skids - load capacity 200 kg",
+ "discount_amount_with_20_percentage_off_storage":"16383",
+ "discount_amount_with_10_percentage_off_minimum_order":"1882"
+ }
+ },
+ "configurable_product": {
+ "sku": "574601",
+ "name":"CP steel cabinet, fire-resistant - 3 adjustable shelves - 1 locker - black gray / light gray"
+ }
+ },
+ "product_offers":{
+ "inactive_offer_with_volume_price":"offer3",
+ "waiting_for_approval_offer_with_volume_price":"offer4",
+ "denied_offer_with_volume_price":"offer404",
+ "active_offer":"offer2",
+ "active_offer_with_merchant_sku":"offer1",
+ "offer_without_volume_price":"offer359",
+ "offer_without_original_price":"offer6",
+ "second_offer_with_volume_price":"offer9",
+ "offer_with_volume_price":"offer10",
+ "offer_with_volume_price_gross_net_prices":"offer48",
+ "active_offer_price":"10160"
+ },
+ "product_attributes":{
+ "brand_1":"Soennecken",
+ "brand_2":"edding",
+ "brand_3":"Mauser",
+ "material_1":"aluminum",
+ "material_2":"metal",
+ "material_3":"chipboard",
+ "material_4":"Steel sheets, stove-enameled",
+ "delivery_1":"assembled",
+ "price_unit_1":"piece",
+ "color_1":"yellow",
+ "color_2":"blue",
+ "color_3":"purple",
+ "color_4":"orange",
+ "product_management_superattribute_id":"farbe",
+ "product_management_attribute_free_input_id":"verschlussart",
+ "product_management_attribute_no_input_id":"bundled_product"
+ },
+ "content":{
+ "abstract_list":{
+ "product_id":"apl-1",
+ "product1_sku":"M21692",
+ "product1_name":"Clairefontaine Collegeblock 8272C DIN A5, 90 sheets",
+ "product2_sku":"M23723",
+ "product2_name":"Brennenstuhl extension cable 3 m",
+ "size":"7"
+ },
+ "banner_1":{
+ "id":"br-1",
+ "name":"Furniture - Upgrade Your Office"
+ },
+ "cms_pages":{
+ "qty":"5",
+ "first_cms_page":{
+ "name":"Imprint",
+ "name_in_lower_case":"imprint",
+ "url_en":"/en/imprint"
+ },
+ "cms_page_with_product_lists":{
+ "id":"10014bd9-4bba-5a54-b84f-31b4b7efd064",
+ "name":"Demo Landing Page"
+ }
+ },
+ "category_collection_name":"Sticky Notes",
+ "category_collection_url":"/en/stationery/paper/sticky-notes",
+ "category_node_is_root_id":"1",
+ "category_node_has_only_parent_id":"37",
+ "category_node_has_children_id":"11",
+ "category_nodes_storage_name":"Foods",
+ "category_nodes_storage_url":"/en/foods",
+ "subcategory_nodes_storage_name":"Vegetables",
+ "subcategory_nodes_storage_url":"/en/foods/vegetables",
+ "cms_page_collection_name":"GTC",
+ "cms_page_collection_url":"/en/gtc",
+ "brand_name":"verbatim",
+ "cart_permission_group_id":"1",
+ "cart_permission_group_type":"cart-permission-groups",
+ "subcategory_nodes_storage_name1":"Fish",
+ "subcategory_nodes_storage_url1":"/en/foods/fish"
+ },
+ "availability":{
+ "stock_is_0":"0.0000000000",
+ "stock_is_20":"20.0000000000"
+ },
+ "misc":{
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "test_cart_name":"Test-cart",
+ "restricted_content_qty":"5",
+ "qty_of_categories_in_category_trees":"6",
+ "qty_of_subcategories_in_category_trees":"2",
+ "color_name":"black",
+ "payment":{
+ "provider_name":"dummyMarketplacePayment",
+ "method_name":"invoice",
+ "selection_name":"dummyMarketplacePaymentInvoice"
+ },
+ "shipment":{
+ "carrier_name":"DHL",
+ "carrier_name_1":"Hermes",
+ "method_name_1":"Standard",
+ "method_name_2":"Express",
+ "method_name_3":"Same Day",
+ "delivery_date":"2030-12-31"
+ },
+ "review":{
+ "title":"This is a review",
+ "text":"This is review text",
+ "default_rating":"5"
+ },
+ "discount_1":{
+ "name":"20% off storage",
+ "description":"Storage sale: 20% off all office storage products",
+ "total_sum_for_discounts_for_products_1_and_2":"16383"
+ },
+ "discount_2":{
+ "name":"10% off minimum order",
+ "description":"Get a 10% discount on all orders above a certain value depending on currency and gross/net price mode",
+ "total_sum_for_discounts_for_products_1_2_and_3":"8435"
+ },
+ "discount_3":{
+ "name":"Free standard delivery",
+ "description":"Get a 10% discount on all orders above a certain value depending on currency and gross/net price mode",
+ "total_sum":"490"
+ },
+ "url_resolver":{
+ "example":"/en/clairefontaine-collegeblock-8272c-din-a5-90blatt-kariert-M21692",
+ "entity_type":"abstract-products",
+ "entity_id":"M21692",
+ "category_nodes":"/en/stationery",
+ "category_nodes_entity":"category-nodes",
+ "category_nodes_id":"2",
+ "cms":"/en/privacy",
+ "cms_entity":"cms-pages",
+ "cms_id":"1e9fb640-9073-55f4-a2d2-535090c92025",
+ "merchant":"/en/merchant/spryker",
+ "merchant_entity":"merchants",
+ "merchant_id":"MER000008"
+ }
+ },
+ "companies":{
+ "company_name":"Spryker Systems GmbH",
+ "user_with_multiple_companies":"anne.boleyn@spryker.com",
+ "company_id":"62de4ab6-b768-5c21-8835-455d9f341625",
+ "company_user_id":"2816dcbd-855e-567e-b26f-4d57f3310bb8",
+ "business_unit":{
+ "address_id":"2175cddd-f8af-5885-b161-227b5c93e72f",
+ "name":"Spryker Systems HR department"
+ }
+ },
+ "labels":{
+ "label_manual":{
+ "id":"3",
+ "name":"Top"
+ },
+ "label_sale":{
+ "id":"5",
+ "name":"SALE %"
+ },
+ "label_new":{
+ "id":"4",
+ "name":"New"
+ },
+ "label_discontinued":{
+ "id":"2",
+ "name":"Discontinued"
+ },
+ "label_alternative":{
+ "id":"1",
+ "name":"Alternatives available"
+ }
+ },
+ "merchants":{
+ "merchants":{
+ "computer_experts":{
+ "merchant_id":"MER000011",
+ "merchant_offer_id":"offer394",
+ "merchant_offer_price":"1234",
+ "concrete_product_with_offer_sku":"425159",
+ "merchant_name":"Computer Experts",
+ "merchant_url":"/en/merchant/computer-experts",
+ "contact_person_role":"Brand Manager",
+ "contact_person_title":"Ms",
+ "contact_person_first_name":"Michele",
+ "contact_person_last_name":"Nemeth",
+ "contact_person_phone":"030/123456789",
+ "public_email":"support@computer-experts.com",
+ "public_phone":"+49 30 234567691",
+ "description":"Computer Experts offer products that enhance your work environment with computer accessories that improve how you work, communicate, and interact. Computer Experts founded in 2013 and continuously growing, acquiring deep industry experience.",
+ "addresses":{
+ "city_munchen":"München",
+ "address1":"Matthias-Pschorr-Straße"
+ }
+ },
+ "merchant_spryker_id":"MER000008",
+ "merchant_office_king_id":"MER000009",
+ "merchant_budget_stationery_id":"MER000010",
+ "merchant_spryker_name":"Spryker",
+ "merchant_spryker_url":"/en/merchant/spryker",
+ "contact_spryker_person_role":"E-Commerce Manager",
+ "contact_spryker_person_title":"Mr",
+ "contact_spryker_person_first_name":"Harald",
+ "contact_spryker_person_last_name":"Schmidt",
+ "contact_spryker_person_phone":"+49 30 208498350",
+ "spryker_public_email":"info@spryker.com",
+ "spryker_public_phone":"+49 30 234567891",
+ "description_spryker":"Spryker is the main merchant on the B2B Demo Marketplace."
+ }
+ },
+ "return_reasons":{
+ "return_reason_damaged":"Damaged",
+ "return_reason_wrong_item":"Wrong Item",
+ "return_reason_no_longer_needed":"No longer needed",
+ "return_reasons_qty":"3"
+ },
+ "productConfigurationInstance": {
+ "productConfigurationInstance":{
+ "displayData": "{\"Preferred time of the day\": \"Afternoon\", \"Date\": \"9.09.2050\"}",
+ "configuration": "{\"time_of_day\": \"3\"}",
+ "configuratorKey": "DATE_TIME_CONFIGURATOR",
+ "isComplete": true
+ },
+ "dummy_api_key":"eba8110c9f9bf5685e8b5f4eba9b17c2",
+ "dummy_key_hash":"f683f48de788d57cd396fc212ef33fd146e1ff0b51cde37ecb4ddd77eeed1706"
+ }
+}
diff --git a/atest/testdata/performance/resources/environments/environments_api_mp_b2c.json b/atest/testdata/performance/resources/environments/environments_api_mp_b2c.json
new file mode 100755
index 0000000..ae13525
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_api_mp_b2c.json
@@ -0,0 +1,762 @@
+{
+ "environment":"api_mp_b2c",
+ "env":{
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env":"5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "dataType":{
+ "array":[
+
+ ]
+ },
+ "users":{
+ "yves_user":{
+ "email":"sonia@spryker.com",
+ "first_name":"Sonia",
+ "last_name":"Wagner",
+ "password":"change123",
+ "password_new":"qweRTY_123456",
+ "password_new_additional":"Change!23456",
+ "reference":"DE--21",
+ "salutation":"Ms"
+ },
+ "Yves_second_user":{
+ "email":"bill.martin@spryker.com",
+ "first_name":"Martin",
+ "last_name":"Bill",
+ "password":"change123",
+ "reference":"DE--4",
+ "salutation":"Mr"
+ },
+ "yves_third_user":{
+ "email":"maxmusterman@spryker.com",
+ "first_name":"Max",
+ "last_name":"Musterman",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "salutation":"Mr"
+ },
+ "yves_eighth_user":{
+ "email":"maria.williams@spryker.com",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "password_new_additional":"qweRTY_123456",
+ "reference":"DE--2"
+ },
+ "yves_ninth_user":{
+ "email":"maggie.may@spryker.com",
+ "first_name":"Maggie",
+ "last_name":"May",
+ "password":"Change!23456",
+ "password_new":"qweRTY_123456",
+ "reference":"DE--3",
+ "salutation":"Ms"
+ },
+ "zed_admin":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "agent":{
+ "email":"admin@spryker.com",
+ "password":"change123"
+ },
+ "non_agent":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "customer_reference":{
+ "de_1":"DE--1",
+ "de_10":"DE--10",
+ "de_15":"DE--15",
+ "de_34":"DE--34"
+ },
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "email":{
+ "name":"sonia",
+ "domain":"@spryker.com"
+ },
+ "gender":{
+ "male":"Male",
+ "female":"Female"
+ },
+ "admin_not_warehouse_user":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ }
+ },
+ "address":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"false",
+ "billing_status":"false"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ }
+ },
+ "search":{
+ "ipp":{
+ "middle":"24",
+ "biggest":"36",
+ "default":"12"
+ },
+ "default_qty":{
+ "ipp_pages":"18",
+ "categories":"14",
+ "colors":"10",
+ "weight":"10",
+ "labels":"4",
+ "materials":"10",
+ "storage_capacity":"5",
+ "touchscreen":"2",
+ "brands":"10",
+ "merchant":"4"
+ },
+ "default_rating":{
+ "min":"4",
+ "max":"5"
+ },
+ "default_price":{
+ "min":"1717",
+ "max":"345699"
+ },
+ "label":{
+ "new":{
+ "id":"4",
+ "name":"New"
+ },
+ "sale":{
+ "id":"5",
+ "name":"SALE %"
+ },
+ "discontinued":{
+ "id":"2",
+ "name":"Discontinued"
+ },
+ "alternatives":{
+ "id":"1",
+ "name":"Alternatives available"
+ },
+ "manual":"Top"
+ },
+ "category_lvl1":{
+ "id":"11",
+ "qty":"39"
+ },
+ "category_lvl2":{
+ "id":"12",
+ "qty":"38"
+ },
+ "category_lvl3":{
+ "id":"13",
+ "qty":"28"
+ },
+ "tree_branches_qty":"6",
+ "node_is_root_id":"1",
+ "node_has_only_parent_id":"6",
+ "node_has_children_id":"5",
+ "abstract_sku_highest_rating":"035",
+ "total_number_of_products_in_search":"212",
+ "total_number_of_products_in_search_1":"211",
+ "sorting_options_qty":"5"
+ },
+ "products":{
+ "bundle_product":{
+ "abstract":{
+ "product_1_sku":"211",
+ "product_2_sku":"150",
+ "product_3_sku":"127",
+ "product_4_sku":"121"
+ },
+ "concrete":{
+ "product_1_sku":"211_123",
+ "product_2_sku":"150_29554292",
+ "product_3_sku":"127_22828284",
+ "product_2_name":"HP Chromebook 11",
+ "product_3_name":"HP Z 620",
+ "product_4_sku":"121_29406823",
+ "product_4_name":"HP 200 280 G1"
+ },
+ "product_name":"HP Bundle"
+ },
+ "discount_concrete_product":{
+ "product_1":{
+ "total_sum_of_discounts":"5600",
+ "total_sum_of_discounts_1":"1400",
+ "with_discount_20_percentage_off_storage":"4000",
+ "with_discount_10_percentage_off_minimum_order":"1600",
+ "with_discount_20_percentage_off_storage_1":"525",
+ "with_discount_10_percentage_off_minimum_order_1":"210"
+ },
+ "product_2":{
+ "sku":"213216",
+ "name":"office akktiv base cabinet - HxWxD 942 x 913 x 420 mm - light gray, RAL 7035",
+ "total_sum_of_discounts":"8096",
+ "sku_1":"007_30691822",
+ "name_1":"Canon IXUS 285",
+ "total_sum_of_discounts_1":"3320",
+ "with_discount_20_percentage_off_storage":"5783",
+ "with_discount_10_percentage_off_minimum_order":"2313",
+ "with_discount_20_percentage_off_storage_1":"2588",
+ "with_discount_10_percentage_off_minimum_order_1":"1035"
+ },
+ "product_3":{
+ "sku":"401768",
+ "with_10_percentage_discount":"490"
+ },
+ "sku_with_voucher_code":"063_29231675"
+ },
+ "discount_1":{
+ "name":"10% off minimum order",
+ "description":"Get a 10% discount on all orders above 100 EUR or 115 CHF",
+ "total_sum_for_discounts_for_products_1_and_2":"1245"
+ },
+ "discount_2":{
+ "name":"20% off cameras",
+ "total_sum_for_discounts_for_products_1_2":"3113",
+ "description":"20% off all digital cameras in the store"
+ },
+ "discount_3":{
+ "name":"Free standard delivery",
+ "total_sum":"490",
+ "description":"Free standard delivery for all orders above certain value depending on the currency",
+ "total_sum_for_discounts_for_products_1_2":"490"
+ },
+ "discount_4":{
+ "name":"5% off white"
+ },
+ "product_options":{
+ "option_1":"OP_2_year_waranty",
+ "option_1_name":"Two (2) year limited warranty",
+ "option_2":"OP_insurance"
+ },
+ "special_product_abstract_sku":{
+ "with_measurement_unit":"M23723",
+ "with_packaging_unit":"M21766"
+ },
+ "product_with_relations":{
+ "has_related_products":{
+ "sku":"204"
+ },
+ "has_alternative_products":{
+ "sku":"M21100"
+ },
+ "has_upselling_products":{
+ "sku":"063",
+ "concrete_sku":"063_29231675"
+ }
+ },
+ "concrete_product_with_alternative":{
+ "sku":"030_30021698",
+ "name":"Canon PowerShot G9 X"
+ },
+ "abstract_product_with_alternative":{
+ "sku":"155",
+ "name":"Lenovo IdeaPad Yoga 500"
+ },
+ "concrete_product":{
+ "product_with_original_prices":{
+ "concrete_sku":"072_21927455",
+ "concrete_name":"Samsung Galaxy Note 3",
+ "abstract_sku":"072"
+ },
+ "product_one_image_set":{
+ "sku":"208_14678762",
+ "name":"Toshiba CAMILEO P20"
+ },
+ "product_multiple_image_set":{
+ "sku":"158_29885222",
+ "name":"Asus ZenPad Z170C"
+ },
+ "product_with_volume_prices":{
+ "concrete_sku":"193_32124735",
+ "abstract_sku":"193",
+ "abstract_name":"TomTom Golf"
+ },
+ "product_without_relations":"019_21081473"
+ },
+ "concrete_of_alternative_product_with_relations_upselling":{
+ "sku":"007_30691822"
+ },
+ "concrete_available_product":{
+ "sku":"183_21811723",
+ "meta_keywords":"Sony,Communication Electronics",
+ "meta_description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos,",
+ "with_label":"204_29851280",
+ "with_stock":"001_25904006",
+ "with_offer":"077_24584210",
+ "without_stock":""
+ },
+ "abstract_available_product_with_stock":{
+ "sku":"183",
+ "price_de":"38168",
+ "price_at":"26432",
+ "name":"Sony Xperia SGP512E1",
+ "description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos, videos and work-related files with you wherever you need to go. The Galaxy Tab S2’s 4:3 ratio display is optimised for magazine reading and web use. Switch to Reading Mode to adjust screen brightness and change wallpaper - create an ideal eBook reading environment designed to reduce the strain on your eyes. Get greater security with convenient and accurate fingerprint functionality. Activate fingerprint lock by pressing the home button. Use fingerprint verification to restrict / allow access to your web browser, screen lock mode and your Samsung account. ",
+ "superattribute":"color",
+ "superAttributesDefinition":"color"
+ },
+ "product_availability":{
+ "concrete_available_with_stock_and_never_out_of_stock_sku":"004_30663302",
+ "concrete_available_with_stock_and_never_out_of_stock_name":"Canon IXUS 175",
+ "abstract_available_product_with_no_stock_and_never_out_of_stock":"154",
+ "abstract_available_with_stock_and_never_out_of_stock":"004",
+ "abstract_available_with_stock_and_never_out_of_stock2":"005",
+ "abstract_unavailable_product":"111"
+ },
+ "concrete_product_with_abstract_product_alternative":{
+ "sku":"138_30657838",
+ "name":"Acer TravelMate P258-M",
+ "name_lower_case":"acer travelmate p258-m"
+ },
+ "concrete_product_with_concrete_product_alternative":{
+ "sku":"155_30149933",
+ "name":"Lenovo IdeaPad Yoga 500",
+ "name_lower_case":"lenovo ideapad yoga 500"
+ },
+ "abstract_available_product_with":{
+ "concretes_3_sku":"127",
+ "concretes_name_3":"HP Z 620",
+ "concretes_superattribute_3":"total_storage_capacity"
+ },
+ "product_related_product_with_upselling_relation":{
+ "sku":"042",
+ "name":"Samsung Galaxy S7"
+ },
+ "product_related_product_with_related_relation":{
+ "sku":"016",
+ "name":"Sony Cyber-shot DSC-W800"
+ },
+ "alternative_abstract_product":{
+ "price_chf":"39675",
+ "sku":"134"
+ },
+ "abstract_product":{
+ "product_with_multiple_variants":{
+ "sku":"130",
+ "variant1_name":"Lenovo ThinkStation P300",
+ "variant1_sku":"130_29285281",
+ "variant2_sku":"130_24326086"
+ },
+ "product_with_label":{
+ "sku":"145",
+ "name":"DELL Chromebook 13"
+ },
+ "product_with_reviews":{
+ "sku":"035",
+ "name":"Canon PowerShot N",
+ "price_chf":"34209"
+ },
+ "product_with_options":{
+ "sku":"012",
+ "name":"Canon IXUS 165"
+ },
+ "product_in_different_locales":{
+ "sku":"001",
+ "name":"Canon IXUS 160",
+ "description_de":"Beeindruckende Aufnahmen",
+ "description_en":"Add a personal touch"
+ }
+ },
+ "products_in_bundle":{
+ "total_qty_of_products":"3",
+ "qty_of_each_product":"1"
+ },
+ "review":{
+ "title":"This is a review",
+ "text":"This is review text",
+ "default_rating":"5"
+ },
+ "configurable_product":{
+ "sku_1":"124_29866591",
+ "sku_2":"124_31623088",
+ "name":"HP ProDesk 400 G3"
+ }
+ },
+ "product_attributes":{
+ "brand_1":"Soennecken",
+ "brand_2":"edding",
+ "brand_3":"Mauser",
+ "brand_4":"Sony",
+ "brand_5":"Lenovo",
+ "material_1":"aluminum",
+ "material_2":"metal",
+ "material_3":"chipboard",
+ "material_4":"Steel sheets, stove-enameled",
+ "internal_memory":"3 GB",
+ "aspect_ratio":"16:10",
+ "storage_media":"flash",
+ "display_technology":"TFT",
+ "delivery_1":"assembled",
+ "price_unit_1":"piece",
+ "color_4":"black",
+ "color_3":"purple",
+ "color_1":"yellow",
+ "color_2":"blue",
+ "product_management_superattribute_id":"4g",
+ "product_management_attribute_free_input_id":"4g_standards",
+ "product_management_attribute_no_input_id":"bundled_product",
+ "return_reason":"Damaged"
+ },
+ "product_offers":{
+ "inactive_offer_with_volume_price":"offer5",
+ "waiting_for_approval_offer_with_volume_price":"offer10",
+ "denied_offer_with_volume_price":"offer404",
+ "active_offer":"offer2",
+ "offer_without_volume_price":"offer359",
+ "offer_without_original_price":"offer6",
+ "second_offer_with_volume_price":"offer348",
+ "offer_with_volume_price":"offer417",
+ "offer_with_volume_price_gross_net_prices":"offer48",
+ "merchant_sony_experts_id":"MER000006",
+ "merchant_video_king_id":"MER000002",
+ "active_offer_price":"10160"
+ },
+ "content":{
+ "abstract_list":{
+ "product_id":"apl-watches",
+ "product1_sku":"083",
+ "product1_name":"Samsung Gear 2 Classic",
+ "product2_sku":"087",
+ "product2_name":"Samsung Gear S2",
+ "size":"4"
+ },
+ "banner":{
+ "id_1":"br-smartwatches",
+ "name_1":"The freedom of cellular"
+ },
+ "cms_pages":{
+ "qty":"5",
+ "first_cms_page":{
+ "name":"Imprint",
+ "name_lower_case":"imprint",
+ "url_en":"/en/imprint"
+ },
+ "cms_page_with_product_lists":{
+ "id":"10014bd9-4bba-5a54-b84f-31b4b7efd064",
+ "name":"Demo Landing Page"
+ }
+ },
+ "category_collection_name":"Digital Cameras",
+ "category_collection_url":"/en/cameras-&-camcorders/digital-cameras",
+ "category_nodes_storage_name":"Cameras & Camcorders",
+ "category_nodes_storage_url":"/en/cameras-&-camcorders",
+ "subcategory_nodes_storage_name":"Digital Cameras",
+ "subcategory_nodes_storage_url":"/en/cameras-&-camcorders/digital-cameras",
+ "brand_name":"canon",
+ "cms_page_collection_name":"GTC",
+ "cms_page_collection_url":"/en/gtc"
+ },
+ "cart":{
+ "x_anonymous_prefix":"anonymous"
+ },
+ "availability":{
+ "stock_is_0":"0.0000000000",
+ "stock_is_20":"20.0000000000",
+ "stock_is_10":"10.0000000000",
+ "stock_is_5":"5.0000000000"
+ },
+ "misc":{
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "test_cart_name":"Test-cart",
+ "qty_of_categories_in_category_trees":"6",
+ "discount_voucher_type_id":"3",
+ "qty_of_subcategories_in_category_trees":"2",
+ "color_name":"black",
+ "payment":{
+ "provider_name":"DummyPayment",
+ "method_name":"Credit Card",
+ "selection_name":"dummyMarketplacePaymentInvoice"
+ },
+ "shipment":{
+ "carrier_name":"DHL",
+ "method_name":"Standard",
+ "method_name_2":"Express",
+ "delivery_date":"2030-12-31"
+ }
+ },
+ "url_resolver":{
+ "url_resolver":{
+ "abstract_product":"/en/canon-ixus-160-1",
+ "product_entity":"abstract-products",
+ "product_id":"001",
+ "category_nodes_url":"/en/computers",
+ "category_nodes_entity":"category-nodes",
+ "category_nodes_id":"5",
+ "cms_url":"/en/privacy",
+ "cms_entity":"cms-pages",
+ "cms_id":"1e9fb640-9073-55f4-a2d2-535090c92025"
+ }
+ },
+ "merchants":{
+ "merchant":{
+ "spryker":{
+ "merchant_id":"MER000001",
+ "merchant_name":"Spryker",
+ "concrete_product_with_offer_sku":"112_312526191",
+ "merchant_url":"/en/merchant/spryker",
+ "contact_person_role":"E-Commerce Manager",
+ "contact_person_title":"Mr",
+ "contact_person_first_name":"Harald",
+ "contact_person_last_name":"Schmidt",
+ "contact_person_phone":"+49 30 208498350",
+ "public_email":"info@spryker.com",
+ "public_phone":"+49 30 234567891",
+ "description":"Spryker is the main merchant on the B2B Demo Marketplace."
+ },
+ "sony_experts":{
+ "merchant_id":"MER000006",
+ "merchant_name":"Sony Experts",
+ "merchant_url":"/en/merchant/sony-experts",
+ "contact_person_role":"Brand Manager",
+ "contact_person_title":"Ms",
+ "contact_person_first_name":"Michele",
+ "contact_person_last_name":"Nemeth",
+ "contact_person_phone":"030/123456789",
+ "public_email":"support@sony-experts.com",
+ "public_phone":"+49 30 234567691",
+ "description":"Capture your moment with the best cameras from Sony. From pocket-size to professional-style, they all pack features to deliver the best quality pictures. Discover the range of Sony cameras, lenses and accessories, and capture your favorite moments with precision and style with the best cameras can offer.",
+ "addresses":{
+ "city_munchen":"München",
+ "address1":"Matthias-Pschorr-Straße"
+ }
+ },
+ "budget_cameras":{
+ "id":"MER000005",
+ "name":"Budget Cameras",
+ "url":"/en/merchant/budget-cameras",
+ "contact_person":{
+ "title":"Mr",
+ "first_name":"Jason",
+ "last_name":"Weidmann",
+ "phone":"030/123456789",
+ "role":"Merchandise Manager"
+ },
+ "public":{
+ "email":"support@budgetcamerasonline.com",
+ "phone":"+49 30 234567591"
+ },
+ "logo_url":"https://d2s0ynfc62ej12.cloudfront.net/merchant/budgetcameras-logo.png"
+ }
+ }
+ },
+ "return_reason":{
+ "return_reasons_qty":"3"
+ },
+ "wishlists":{
+ "wishlist_name":"HS"
+ },
+ "productConfigurationInstance":{
+ "productConfigurationInstance":{
+ "displayData":"{\"Preferred time of the day\": \"Afternoon\", \"Date\": \"9.09.2050\"}",
+ "configuration":"{\"time_of_day\": \"3\"}",
+ "configuratorKey":"DATE_TIME_CONFIGURATOR",
+ "isComplete":true
+ }
+ },
+ "dummy_api_key":"eba8110c9f9bf5685e8b5f4eba9b17c2",
+ "dummy_key_hash":"f683f48de788d57cd396fc212ef33fd146e1ff0b51cde37ecb4ddd77eeed1706",
+ "servicePoints":{
+ "default_service_points":{
+ "sp1":{
+ "key":"sp1",
+ "name":"Spryker Main Store"
+ },
+ "sp2":{
+ "key":"sp2",
+ "name":"Spryker Berlin Store"
+ }
+ },
+ "dynamic_service":{
+ "service_point_name":"robot",
+ "service_point_key":"robot",
+ "service_point_address_line_1":"Park Avenue",
+ "service_point_address_line_2":"Building 22",
+ "service_point_address_city":"robot",
+ "service_point_address_zip_code":"12345",
+ "service_point_address_country":"DE",
+ "service_type_name":"robot",
+ "service_type_key":"robot",
+ "service_key":"robot"
+ },
+ "servicePoints":[
+ {
+ "uuid":"test-service-point",
+ "name":"TSP",
+ "key":"tsp"
+ },
+ {
+ "uuid":"test-service-point-2",
+ "name":"TSP2",
+ "key":"tsp2"
+ }
+ ],
+ "servicePointAddresses":[
+ {
+ "uuid":"test-service-point-address",
+ "address1":"Test address",
+ "address2":"Test address 2",
+ "address3":"Test address 3",
+ "city":"City",
+ "zipCode":"10115"
+ }
+ ],
+ "services":[
+ {
+ "uuid":"test-service",
+ "key":"ts"
+ }
+ ],
+ "serviceTypes":[
+ {
+ "uuid":"test-service-type",
+ "name":"Test service type",
+ "key":"tst"
+ }
+ ]
+ },
+ "warehouses":{
+ "warehouses":[
+ {
+ "uuid":"test-warehouse",
+ "is_active":true,
+ "name":"Test warehouse"
+ }
+ ]
+ },
+ "push_notifications":{
+ "push_notification_subscriptions":[
+ {
+ "providerName":"web-push-php",
+ "group":{
+ "name":"warehouse",
+ "identifier":""
+ },
+ "payload":{
+ "endpoint":"endpoint",
+ "publicKey":"publicKey",
+ "authToken":"authToken"
+ },
+ "localeName":""
+ }
+ ]
+ },
+ "push_notification_providers":{
+ "push_notification_provider_uuid":"2a304ddf-d51b-514f-bd11-6e818a27fe23"
+ },
+ "shipment_type":{
+ "shipment_type_uuid":"174d9dc0-55ae-5c4b-a2f2-a419027029ef",
+ "shipment_type_name":"Pickup"
+ },
+ "warehouse_user_assignment":{
+ "warehouse_user":[
+ {
+ "user_uuid":"48a6c610-693e-5d88-bdce-3c6018b3abd2",
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f",
+ "user_uuid_2":"84b8f847-d755-5763-b128-8e138e6571fc",
+ "user_uuid_3":"8565d483-70cd-5c73-bc6a-96d2e70ddee1",
+ "user_name":"martha@video-king.nl",
+ "user_first_name":"Martha",
+ "user_last_name":"Farmer",
+ "admin_user_name":"admin@spryker.com",
+ "admin_user_first_name":"Admin",
+ "admin_user_last_name":"Spryker"
+ }
+ ],
+ "warehouse":[
+ {
+ "warehouse_uuid":"e84b3cb8-a94a-5a7e-9adb-cc5353f7a73f",
+ "warehouse_uuid_budjet_cameras":"86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "warehouse_name":"Spryker MER000001 Warehouse 1",
+ "warehouse_name_budjet_cameras":"Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid":"62372576-6a2b-5a71-9e9c-737bc47b0bf1",
+ "video_king_warehouse_name":"Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker":"9"
+ }
+ ]
+ },
+ "demo_service_point":{
+ "spryker_main_store":{
+ "uuid":"262feb9d-33a7-5c55-9b04-45b1fd22067e",
+ "uuid2":"7e3b03e0-c53c-5298-9ece-968f4628b4f8",
+ "name":"Spryker Main Store",
+ "key":"sp1"
+ },
+ "service_point_address":{
+ "uuid":"74768ee9-e7dd-5e3c-bafd-b654e7946c54",
+ "uuid2":"7a711afc-02ce-5f54-a08c-fadfaf5713c6",
+ "address1":"Julie-Wolfthorn-Straße",
+ "address2":"1",
+ "address3":"None",
+ "city":"Berlin",
+ "zip":"10115"
+ }
+ }
+}
diff --git a/atest/testdata/performance/resources/environments/environments_api_suite.json b/atest/testdata/performance/resources/environments/environments_api_suite.json
new file mode 100644
index 0000000..a4473b9
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_api_suite.json
@@ -0,0 +1,939 @@
+{
+ "environment":"api_suite",
+ "env":{
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env":"5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user":{
+ "email":"sonia@spryker.com",
+ "first_name":"Sonia",
+ "last_name":"Wagner",
+ "password":"change123",
+ "password_new":"qweRTY_123456",
+ "password_new_additional":"Change!23456",
+ "reference":"DE--21",
+ "salutation":"Ms"
+ },
+ "yves_second_user":{
+ "email":"bill.martin@spryker.com",
+ "first_name":"Martin",
+ "last_name":"Bill",
+ "password":"change123",
+ "reference":"DE--4",
+ "salutation":"Mr"
+ },
+ "yves_third_user":{
+ "email":"maxmusterman@spryker.com",
+ "first_name":"Max",
+ "last_name":"Musterman",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "salutation":"Mr"
+ },
+ "yves_fourth_user":{
+ "email":"Lilu@ottom.de",
+ "first_name":"Lilu",
+ "last_name":"Dallas",
+ "password":"change123",
+ "reference":"DE--22",
+ "salutation":"Ms"
+ },
+ "yves_fifth_user":{
+ "email":"Trever.m@spryker.com",
+ "password":"change123",
+ "reference":"DE--20"
+ },
+ "yves_sixth_user":{
+ "email":"kevin@spryker.com",
+ "password":"change123"
+ },
+ "yves_seventh_user":{
+ "email":"andrew@ottom.de",
+ "password":"change123"
+ },
+ "yves_eighth_user":{
+ "email":"maria.williams@spryker.com",
+ "password":"change123",
+ "password_new":"Change!23456",
+ "password_new_additional":"qweRTY_123456",
+ "reference":"DE--2"
+ },
+ "yves_ninth_user":{
+ "email":"maggie.may@spryker.com",
+ "first_name":"Maggie",
+ "last_name":"May",
+ "password":"Change!23456",
+ "password_new":"qweRTY_123456",
+ "reference":"DE--3",
+ "salutation":"Ms"
+ },
+ "zed_admin":{
+ "email":"admin@spryker.com",
+ "email_de":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "zed_user":{
+ "email":"michele@sony-experts.com"
+ },
+ "gender":{
+ "female":"Female",
+ "male":"Male"
+ },
+ "email":{
+ "name":"sonia",
+ "domain":"@spryker.com"
+ },
+ "agent":{
+ "email":"agent123@spryker.com",
+ "password":"change123"
+ },
+ "non_agent":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "yves_shared_shopping_list_user":{
+ "email":"Trever.m@spryker.com",
+ "first_name":"Trever",
+ "last_name":"Meier",
+ "password":"change123",
+ "salutation":"Mr"
+ },
+ "yves_shared_shopping_cart_user":{
+ "email":"Solomon@spryker.com",
+ "first_name":"Solomon",
+ "last_name":"Wesner",
+ "password":"change123",
+ "salutation":"Mr"
+ }
+ },
+ "address":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"false",
+ "billing_status":"false"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ }
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ }
+ },
+ "products":{
+ "bundle_product":{
+ "bundle_product_product_name":"HP Bundle",
+ "abstract":{
+ "sku":"211",
+ "product_1_sku":"121",
+ "product_2_sku":"127",
+ "product_3_sku":"150"
+ },
+ "concrete":{
+ "product_1_sku":"121_29406823",
+ "product_2_sku":"127_22828284",
+ "product_3_sku":"150_29554292",
+ "product_4_sku":"211_123"
+ },
+ "qty_of_products_in_bundle":"3",
+ "qty_of_each_product_inside_bundle":"1"
+ },
+ "bundled_product":{
+ "concrete":{
+ "product_1_sku":"211_123",
+ "product_1_name":"HP Bundle",
+ "product_2_sku":"150_29554292",
+ "product_2_name":"HP Chromebook 11",
+ "product_3_sku":"127_22828284",
+ "product_3_name":"HP Z 620",
+ "product_4_sku":"121_29406823",
+ "product_4_name":"HP 200 280 G1"
+ }
+ },
+ "special_product_abstract_sku":{
+ "with_multivariant":"051",
+ "with_measurement_unit":"215",
+ "with_packaging_unit":"218"
+ },
+ "concrete":{
+ "available_product":{
+ "with_stock_and_never_out_of_stock":{
+ "sku":"208_14678762",
+ "name":"Toshiba CAMILEO P20",
+ "sku_1":"005_30663301",
+ "sku_2":"006_30692993"
+ },
+ "with_stock":{
+ "sku":"001_25904006",
+ "name":"Canon IXUS 160",
+ "sku2":"112_306918002",
+ "name2":"Acer Extensa M2610",
+ "sku3":"183_21811723"
+ },
+ "without_stock":{
+ "sku":"192_17738941",
+ "name":"Samsung F90BN"
+ }
+ }
+ },
+ "admin_not_warehouse_user":{
+ "email":"admin_de@spryker.com",
+ "password":"change123"
+ },
+ "product_with_relations":{
+ "has_related_products":{
+ "sku":"200"
+ },
+ "has_alternative_products":{
+ "sku":"145"
+ },
+ "has_upselling_products":{
+ "sku":"063",
+ "concrete_sku":"063_29231675"
+ }
+ },
+ "concrete_products":{
+ "sku_1":"133_31743669",
+ "sku_2":"140_22766487",
+ "sku_3":"141_29380410",
+ "one_image_set":{
+ "sku":"208_14678762",
+ "name":"Toshiba CAMILEO P20"
+ },
+ "multiple_image_set":{
+ "sku":"158_29885222",
+ "set_name":"Asus ZenPad Z170C"
+ }
+ },
+ "product_related_product_with_upselling_relation":{
+ "sku":"042",
+ "name":"Samsung Galaxy S7"
+ },
+ "concrete_of_alternative_product_with_relations_upselling":{
+ "sku":"007_30691822"
+ },
+ "product_with_alternative":{
+ "concrete_sku":"138_30046855",
+ "concrete_name":"Acer TravelMate P258-M",
+ "abstract_sku":"138"
+ },
+ "product_related_product_with_related_relation":{
+ "sku":"016",
+ "name":"Sony Cyber-shot DSC-W800"
+ },
+ "concrete_product_with_alternative":{
+ "sku":"134_29759322",
+ "abstract_sku":"134",
+ "price_de":"1879",
+ "price_at":"1503",
+ "name":"Acer Aspire S7",
+ "name_lower_case":"acer aspire s7",
+ "product_sku1":"014_25919241",
+ "product_sku1_name":"Canon IXUS 177"
+ },
+ "abstract_product_with_alternative":{
+ "sku":"155",
+ "name":"DELL Chromebook 13"
+ },
+ "alternative_abstract_product":{
+ "sku":"155",
+ "price_chf":"42090",
+ "price_chf_1":"51778"
+ },
+ "abstract_available_product_with_stock":{
+ "sku":"183",
+ "concrete_sku":"183_21811723",
+ "name":"Sony Xperia SGP512E1",
+ "description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos, videos and work-related files with you wherever you need to go. The Galaxy Tab S2’s 4:3 ratio display is optimised for magazine reading and web use. Switch to Reading Mode to adjust screen brightness and change wallpaper - create an ideal eBook reading environment designed to reduce the strain on your eyes. Get greater security with convenient and accurate fingerprint functionality. Activate fingerprint lock by pressing the home button. Use fingerprint verification to restrict / allow access to your web browser, screen lock mode and your Samsung account. ",
+ "superattribute":"color"
+ },
+ "abstract_product_with_merchant":{
+ "sku":"017",
+ "concrete_sku":"017_21748906",
+ "name":"Sony Cyber-shot DSC-W800",
+ "description":"Styled for your pocket Precision photography meets the portability of a smartphone. The W800 is small enough to take great photos, look good while doing it, and slip in your pocket. Shooting great photos and videos is easy with the W800. Buttons are positioned for ease of use, while a dedicated movie button makes shooting movies simple. The vivid 2.7-type Clear Photo LCD display screen lets you view your stills and play back movies with minimal effort. Whip out the W800 to capture crisp, smooth footage in an instant. At the press of a button, you can record blur-free 720 HD images with digital sound. Breathe new life into a picture by using built-in Picture Effect technology. There’s a range of modes to choose from – you don’t even have to download image-editing software.",
+ "merchant_refference":"MER000001"
+ },
+ "concrete_available_product":{
+ "with_offer":"030_30021698",
+ "with_label":"006_30692993",
+ "sku":"183_21811723",
+ "meta_keywords":"Sony,Communication Electronics",
+ "meta_description":"Enjoy greater flexibility ...than ever before with the Galaxy Tab S2. Remarkably slim and ultra-lightweight, use this device to take your e-books, photos,"
+ },
+ "product_availability":{
+ "abstract_available_with_stock_and_never_out_of_stock":"005",
+ "abstract_available_product_with_no_stock_and_never_out_of_stock":"666",
+ "abstract_unavailable_product":"189",
+ "concrete_available_with_stock_and_never_out_of_stock_sku":"005_30663301",
+ "concrete_available_with_stock_and_never_out_of_stock_sku_name":"Canon IXUS 175",
+ "concrete_unavailable_product":"192_17738941",
+ "concrete_available_with_stock_and_never_out_of_stock":"002_25904004",
+ "concrete_available_with_stock_and_never_out_of_stock_name":"Canon IXUS 160",
+ "abstract_available_with_stock_and_never_out_of_stock_2":"007",
+ "concrete_available_with_stock_and_never_out_of_stock_sku_2":"009_30692991"
+ },
+ "concrete_product_with_concrete_product_alternative":{
+ "sku":"155_30149933",
+ "name":"Lenovo IdeaPad Yoga 500",
+ "name_lower_case":"lenovo ideapad yoga 500"
+ },
+ "abstract_product_with_variants":{
+ "concretes_3":"177",
+ "variant1_sku":"177_24867659",
+ "variant2_sku":"177_24422865",
+ "concretes_name_3":"Samsung Galaxy Tab Active 8.0 8 GB",
+ "concretes_superattribute_3":"internal_storage_capacity"
+ },
+ "abstract_product":{
+ "product_with_volume_prices":{
+ "sku":"093",
+ "name":"Sony SmartWatch 3"
+ },
+ "product_with_original_prices":{
+ "sku":"203"
+ },
+ "product_with_label":{
+ "sku":"001",
+ "name":"Canon IXUS 160",
+ "description_de":"Beeindruckende Aufnahmen",
+ "description_en":"Add a personal touch"
+ },
+ "product_with_reviews":{
+ "sku":"093",
+ "name":"Sony SmartWatch 3",
+ "qty":"4"
+ },
+ "product_with_options":{
+ "sku":"093",
+ "name":"Sony SmartWatch 3"
+ },
+ "product_with_concrete_offers":{
+ "sku":"006",
+ "concrete_sku":"006_30692993",
+ "name":"Canon IXUS 175",
+ "concretes_count":"1"
+ },
+ "product_with_multiple_variants":{
+ "sku":"199",
+ "variant1_name":"Sony HXR-MC2500",
+ "variant1_sku":"199_7016823",
+ "variant2_sku":"199_24788780"
+ }
+ },
+ "configurable_bundle":{
+ "slot_1":{
+ "product_1":"193_32124735",
+ "product_no_stock":"192_17738941"
+ },
+ "slot_5":{
+ "product_1":"005_30663301",
+ "product_2":"008_30692992"
+ },
+ "slot_6":{
+ "product_1":"201_11217755"
+ }
+ },
+ "concrete_product":{
+ "product_with_concrete_offers":{
+ "sku":"112_312526191",
+ "name":"Acer Extensa M2610"
+ },
+ "one_image_set":{
+ "sku":"208_14678762",
+ "name":"Toshiba CAMILEO P20"
+ },
+ "original_prices":{
+ "sku":"072_21927455",
+ "name":"Samsung Galaxy Note 3"
+ },
+ "product_with_original_prices":{
+ "concrete_sku":"072_21927455",
+ "concrete_name":"Samsung Galaxy Note 3",
+ "abstract_sku":"072"
+ },
+ "product_with_volume_prices":{
+ "concrete_sku":"193_32124735",
+ "abstract_sku":"193",
+ "abstract_name":"TomTom Golf"
+ },
+ "with_review":{
+ "sku":"086_30521602",
+ "name":"Samsung Gear S2"
+ },
+ "product_with_sales_and_measurement_units":{
+ "sku":"cable-vga-1-1",
+ "name":"VGA cable (1.5m)"
+ },
+ "random_weight":{
+ "sku":"cable-vga-1-2",
+ "name":"VGA cable as long as you want",
+ "measurement_unit":"19",
+ "qty_of_units":"2",
+ "amount":"5.0000000000",
+ "conversion":"1",
+ "precision":"100",
+ "packaging_unit":"19"
+ },
+ "product_without_relations":"019_21081473"
+ },
+ "discount_concrete_product":{
+ "product_1":{
+ "total_sum_of_discounts":"5600",
+ "total_sum_of_discounts_1":"1400",
+ "with_discount_20_percentage_off_storage":"4000",
+ "with_discount_10_percentage_off_minimum_order":"1600",
+ "discount_20_percentage_off_cameras_amount":"2000",
+ "discount_10_percentage_off_above_100_amount":"800",
+ "sku":"002_25904004",
+ "name":"Canon IXUS 160"
+ },
+ "product_2":{
+ "total_sum_of_discounts":"8096",
+ "sku":"007_30691822",
+ "name":"Canon IXUS 285",
+ "total_sum_of_discounts_1":"3320",
+ "with_discount_20_percentage_off_storage":"5783",
+ "with_discount_10_percentage_off_minimum_order":"2313",
+ "discount_20_percentage_off_cameras_amount":"6900",
+ "discount_10_percentage_off_above_100_amount":"2760"
+ }
+ },
+ "configurable_product":{
+ "sku":"093_24495843",
+ "name":"Sony SmartWatch 3"
+ },
+ "discount_1":{
+ "name":"10% off minimum order",
+ "description":"Get a 10% discount on all orders above 100 EUR or 115 CHF",
+ "total_sum_for_discounts_for_products_1_and_2":"3560"
+ },
+ "discount_2":{
+ "name":"20% off cameras",
+ "total_sum_for_discounts_for_products_1_2":"8900",
+ "description":"20% off all digital cameras in the store"
+ },
+ "discount_3":{
+ "name":"Free standard delivery",
+ "total_sum":"490",
+ "description":"Free standard delivery for all orders above certain value depending on the currency",
+ "total_sum_for_discounts_for_products_1_2":"490"
+ }
+ },
+ "discount":{
+ "voucher":{
+ "name":"5% off white"
+ },
+ "product_with_voucher_code":{
+ "concrete_sku":"058_24245592"
+ }
+ },
+ "shopping-list":{
+ "shopping_list_name":"My Shopping List",
+ "1st_shopping_list":{
+ "id":"cf032865-d1ad-5e27-803a-423bd15ced66",
+ "name":"Newcomers"
+ }
+ },
+ "product_offers":{
+ "inactive_offer_with_volume_price":"offer5",
+ "waiting_for_approval_offer_with_volume_price":"offer10",
+ "denied_offer_with_volume_price":"offer404",
+ "active_offer_2":"offer54",
+ "active_offer":"offer13",
+ "offer_with_merchant_sku":"offer1",
+ "offer_without_volume_price":"offer359",
+ "offer_without_original_price":"offer6",
+ "second_offer_with_volume_price":"offer415",
+ "offer_with_volume_price":"offer417",
+ "offer_with_volume_price_gross_net_prices":"offer48",
+ "active_offer_price":"32775",
+ "merchant_sony_experts_id":"MER000005",
+ "merchant_video_king_id":"MER000002"
+ },
+ "product_attributes":{
+ "internal_memory":"3 GB",
+ "aspect_ratio":"16:10",
+ "storage_media":"flash",
+ "display_technology":"TFT",
+ "color_5":"black",
+ "brand_1":"Acer",
+ "brand_2":"edding",
+ "brand_3":"Mauser",
+ "brand_4":"Sony",
+ "material_1":"aluminum",
+ "material_2":"metal",
+ "material_3":"chipboard",
+ "material_4":"Steel sheets, stove-enameled",
+ "delivery_1":"assembled",
+ "price_unit_1":"piece",
+ "color_1":"yellow",
+ "color_2":"Blue",
+ "color_3":"purple",
+ "color_4":"orange",
+ "product_management":{
+ "superattribute_id":"4g",
+ "attribute_free_input_id":"4g_standards",
+ "attribute_no_input_id":"bundled_product"
+ }
+ },
+ "content":{
+ "abstract_product_list":{
+ "id":"apl-1",
+ "product1_sku":"204",
+ "product1_name":"Sony PXW-FS5K",
+ "product2_sku":"205",
+ "product2_name":"Toshiba CAMILEO S30",
+ "size":"2"
+ },
+ "banner_1":{
+ "id":"br-1",
+ "title":"banner title 1"
+ },
+ "cms_pages":{
+ "qty":"6",
+ "first_cms_page":{
+ "name":"Imprint",
+ "name_lower_case":"imprint",
+ "url_en":"/en/imprint"
+ },
+ "cms_page_with_product_lists":{
+ "id":"10014bd9-4bba-5a54-b84f-31b4b7efd064",
+ "name":"Demo Landing Page"
+ }
+ },
+ "category_collection_name":"Digital Cameras",
+ "category_collection_url":"/en/cameras-&-camcorders/digital-cameras",
+ "cms_page_collection_name":"GTC",
+ "brand_name":"canon",
+ "cms_page_collection_url":"/en/gtc",
+ "category_nodes_storage_name":"Cameras & Camcorders",
+ "category_nodes_storage_url":"/en/cameras-&-camcorders",
+ "subcategory_nodes_storage_name":"Digital Cameras",
+ "subcategory_nodes_storage_url":"/en/cameras-&-camcorders/digital-cameras",
+ "category_node_is_root_id":"1",
+ "category_node_has_only_parent_id":"12",
+ "category_node_has_children_id":"11"
+ },
+ "companies":{
+ "company_name":"Spryker Systems GmbH",
+ "business_unit_address_id":"2175cddd-f8af-5885-b161-227b5c93e72f",
+ "business_unit_name":"Spryker Systems HR department",
+ "user_with_multiple_companies":"anne.boleyn@spryker.com",
+ "company_id":"62de4ab6-b768-5c21-8835-455d9f341625",
+ "company_user_id":"2816dcbd-855e-567e-b26f-4d57f3310bb8",
+ "busines_unit_address_id":"2175cddd-f8af-5885-b161-227b5c93e72f"
+ },
+ "search":{
+ "ipp":{
+ "default":"12",
+ "middle":"24",
+ "biggest":"36",
+ "default_2":"2",
+ "default_3":"6"
+ },
+ "default_qty":{
+ "ipp_pages":"19",
+ "categories":"20",
+ "colors":"10",
+ "labels":"8",
+ "materials":"7",
+ "material":"5",
+ "brands":"10",
+ "sorting_options":"6",
+ "product_classes":"2"
+ },
+ "default_price_range":{
+ "min":"0",
+ "max":"345699"
+ },
+ "default_active":{
+ "min":"3454",
+ "max":"39353"
+ },
+ "label":{
+ "new":"New",
+ "sale":"SALE %",
+ "manual":"Top",
+ "discontinued":"Discontinued",
+ "alternatives":"Alternatives available"
+ },
+ "category_lvl1":{
+ "id":"11",
+ "qty":"39"
+ },
+ "category_lvl2":{
+ "id":"12",
+ "qty":"38"
+ },
+ "category_lvl3":{
+ "id":"13",
+ "qty":"5"
+ },
+ "category_tree_branches_qty":"7",
+ "total_number_of_products_in_search":"218",
+ "min_number_of_products_in_search":"215",
+ "max_number_of_products_in_search":"225",
+ "abstract_sku_highest_rating":"035"
+ },
+ "availability":{
+ "stock_is_0":"0.0000000000",
+ "stock_is_20":"20.0000000000"
+ },
+ "labels":{
+ "label_standard":{
+ "id":"3",
+ "name":"Standard Label"
+ },
+ "label_sale":{
+ "id":"5",
+ "name":"SALE %"
+ },
+ "label_new":{
+ "id":"4",
+ "name":"New"
+ },
+ "label_discontinued":{
+ "id":"2",
+ "name":"Discontinued"
+ },
+ "label_alternative":{
+ "id":"1",
+ "name":"Alternatives available"
+ }
+ },
+ "misc":{
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "qty_of_categories_in_category_trees":"7",
+ "discount_voucher_type_id":"3",
+ "color_name":"Black",
+ "x_anonymous_prefix":"anonymous",
+ "qty_of_subcategories_in_category_trees":"2",
+ "gift_card":{
+ "amount":"10000",
+ "paymentProvider":"GiftCard",
+ "paymentMethod":"GiftCard"
+ },
+ "review":{
+ "title":"This is a review",
+ "text":"This is review text",
+ "default_rating":"5"
+ },
+ "cart_permission_group_id":"1",
+ "cart_permission_group_id_2":"2",
+ "test_cart_name":"Test-cart",
+ "payment":{
+ "provider_name":"dummyMarketplacePayment",
+ "method_name":"Invoice",
+ "selection_name":"dummyMarketplacePaymentInvoice",
+ "provider_name_1":"DummyPayment",
+ "method_name_1":"Credit Card"
+ },
+ "shipment":{
+ "carrier_name":"Spryker Dummy Shipment",
+ "method_name_1":"Standard",
+ "method_name_2":"Express",
+ "delivery_date":"2030-12-31",
+ "method_1":{
+ "name":"Standard",
+ "id":"1",
+ "carrier_name":"Spryker Dummy Shipment",
+ "price_eur":"490",
+ "price_chf":"560"
+ }
+ },
+ "packaging_unit":{
+ "m":"METR",
+ "cm":"CMET",
+ "m_name":"Meter"
+ },
+ "measurement_unit":{
+ "m":"METR"
+ }
+ },
+ "quote_requests":{
+ "quote_request":{
+ "purchase_order_number":"7711",
+ "delivery_date":"2023-12-31",
+ "note":"Test note",
+ "cart_permission_id":"2"
+ }
+ },
+ "return_reason":{
+ "return_reasons_qty":"3",
+ "return_reason_damaged":"Damaged"
+ },
+ "merchants":{
+ "merchants":{
+ "sony_experts":{
+ "merchant_reference":"MER000006",
+ "merchant_name":"Sony Experts",
+ "merchant_url":"/en/merchant/sony-experts",
+ "contact_person_role":"Brand Manager",
+ "contact_person_title":"Ms",
+ "contact_person_first_name":"Michele",
+ "contact_person_last_name":"Nemeth",
+ "contact_person_phone":"030/123456789",
+ "public_email":"support@sony-experts.com",
+ "public_phone":"+49 30 234567691",
+ "merchant_offer_id":"offer350",
+ "concrete_product_with_offer_sku":"195_25904159",
+ "description":"Capture your moment with the best cameras from Sony. From pocket-size to professional-style, they all pack features to deliver the best quality pictures. Discover the range of Sony cameras, lenses and accessories, and capture your favorite moments with precision and style with the best cameras can offer.",
+ "addresses":{
+ "city_munchen":"München",
+ "address1":"Matthias-Pschorr-Straße"
+ }
+ },
+ "spryker":{
+ "merchant_reference":"MER000001"
+ }
+ }
+ },
+ "wishlists":{
+ "wishlist_name":"HS"
+ },
+ "url_resolver":{
+ "url_resolver_abstract_product":"/en/acer-aspire-s7-134",
+ "url_resolver_product_entity":"abstract-products",
+ "url_resolver_product_id":"134",
+ "url_resolver_category_nodes":"/en/computer/notebooks",
+ "url_resolver_category_nodes_entity":"category-nodes",
+ "url_resolver_category_nodes_id":"6",
+ "url_resolver_cms":"/en/privacy",
+ "url_resolver_cms_entity":"cms-pages",
+ "url_resolver_cms_id":"1e9fb640-9073-55f4-a2d2-535090c92025",
+ "url_resolver_merchant":"/en/merchant/spryker",
+ "url_resolver_merchant_entity":"merchants",
+ "url_resolver_merchant_id":"MER000001"
+ },
+ "configurable_bundles":{
+ "configurable_bundle_template_1_uuid":"8d8510d8-59fe-5289-8a65-19f0c35a0089",
+ "configurable_bundle_first_slot_item_sku":"001_25904006",
+ "configurable_bundle_first_slot_item_sku2":"134_29759322",
+ "configurable_bundle_fifth_slot_item_sku":"112_306918002",
+ "configurable_bundle_slot_1_uuid":"332b40ac-a789-57ce-bec0-23d8dddd71eb",
+ "configurable_bundle_template_2_uuid":"c8291fd3-c6ca-5b8f-8ff5-eccd6cb787de",
+ "configurable_bundle_slot_5_uuid":"9626de80-6caa-57a9-a683-2846ec5b6914",
+ "configurable_bundle_slot_6_uuid":"2a5e55b1-993a-5510-864c-a4a18558aa75",
+ "configurable_bundle_template_name_1":"Configurable Bundle \"All in\"",
+ "configurable_bundle_template_name_2":"Smartstation Kit",
+ "configured_bundle_quantity":2,
+ "configurable_bundle_first_slot_item_name":"Canon IXUS 160",
+ "configurable_bundle_first_slot_item_name2":"Acer Aspire S7"
+ },
+ "productConfigurationInstance":{
+ "productConfigurationInstance":{
+ "displayData":"{\"Preferred time of the day\": \"Afternoon\", \"Date\": \"9.09.2050\"}",
+ "configuration":"{\"time_of_day\": \"3\"}",
+ "configuratorKey":"DATE_TIME_CONFIGURATOR",
+ "isComplete":true
+ }
+ },
+ "dataType":{
+ "arrow":[
+
+ ]
+ },
+ "servicePoints":{
+ "default_service_points":{
+ "sp1":{
+ "key":"sp1",
+ "name":"Spryker Main Store"
+ },
+ "sp2":{
+ "key":"sp2",
+ "name":"Spryker Berlin Store"
+ }
+ },
+ "dynamic_service":{
+ "service_point_name":"robot",
+ "service_point_key":"robot",
+ "service_point_address_line_1":"Park Avenue",
+ "service_point_address_line_2":"Building 22",
+ "service_point_address_city":"robot",
+ "service_point_address_zip_code":"12345",
+ "service_point_address_country":"DE",
+ "service_type_name":"robot",
+ "service_type_key":"robot",
+ "service_key":"robot"
+ },
+ "servicePoints":[
+ {
+ "uuid":"test-service-point",
+ "name":"TSP",
+ "key":"tsp"
+ },
+ {
+ "uuid":"test-service-point-2",
+ "name":"TSP2",
+ "key":"tsp2"
+ }
+ ],
+ "servicePointAddresses":[
+ {
+ "uuid":"test-service-point-address",
+ "address1":"Test address",
+ "address2":"Test address 2",
+ "address3":"Test address 3",
+ "city":"City",
+ "zipCode":"10115"
+ }
+ ],
+ "services":[
+ {
+ "uuid":"test-service",
+ "key":"ts"
+ }
+ ],
+ "serviceTypes":[
+ {
+ "uuid":"test-service-type",
+ "name":"Test service type",
+ "key":"tst"
+ }
+ ]
+ },
+ "warehouses":{
+ "warehouses":[
+ {
+ "uuid":"test-warehouse",
+ "is_active":true,
+ "name":"Test warehouse"
+ }
+ ]
+ },
+ "push_notifications":{
+ "push_notification_subscriptions":[
+ {
+ "providerName":"web-push-php",
+ "group":{
+ "name":"warehouse",
+ "identifier":""
+ },
+ "payload":{
+ "endpoint":"endpoint",
+ "publicKey":"publicKey",
+ "authToken":"authToken"
+ },
+ "localeName":""
+ }
+ ]
+ },
+ "push_notification_providers":{
+ "push_notification_provider_uuid":"2a304ddf-d51b-514f-bd11-6e818a27fe23"
+ },
+ "shipment_type":{
+ "shipment_type_uuid":"174d9dc0-55ae-5c4b-a2f2-a419027029ef",
+ "shipment_type_name":"Pickup"
+ },
+ "warehouse_user_assignment":{
+ "warehouse_user":[
+ {
+ "user_uuid":"48a6c610-693e-5d88-bdce-3c6018b3abd2",
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f",
+ "user_uuid_2":"84b8f847-d755-5763-b128-8e138e6571fc",
+ "user_uuid_3":"8565d483-70cd-5c73-bc6a-96d2e70ddee1",
+ "user_name":"martha@video-king.nl",
+ "user_first_name":"Martha",
+ "user_last_name":"Farmer"
+ }
+ ],
+ "warehouse":[
+ {
+ "warehouse_uuid":"e84b3cb8-a94a-5a7e-9adb-cc5353f7a73f",
+ "warehouse_uuid_budjet_cameras":"86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "warehouse_name":"Spryker MER000001 Warehouse 1",
+ "warehouse_name_budjet_cameras":"Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid":"62372576-6a2b-5a71-9e9c-737bc47b0bf1",
+ "video_king_warehouse_name":"Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker":"9"
+ }
+ ],
+ "demo_service_point":{
+ "spryker_main_store":{
+ "uuid":"262feb9d-33a7-5c55-9b04-45b1fd22067e",
+ "uuid2":"7e3b03e0-c53c-5298-9ece-968f4628b4f8",
+ "name":"Spryker Main Store",
+ "key":"sp1"
+ }
+ },
+ "service_point_address":{
+ "uuid":"74768ee9-e7dd-5e3c-bafd-b654e7946c54",
+ "uuid2":"7a711afc-02ce-5f54-a08c-fadfaf5713c6",
+ "address1":"Julie-Wolfthorn-Straße",
+ "address2":"1",
+ "address3":"None",
+ "city":"Berlin",
+ "zip":"10115"
+ }
+ },
+ "dynamic_entity":{
+ "dummy_api_key":"eba8110c9f9bf5685e8b5f4eba9b17c2",
+ "dummy_key_hash":"f683f48de788d57cd396fc212ef33fd146e1ff0b51cde37ecb4ddd77eeed1706"
+ }
+}
diff --git a/atest/testdata/performance/resources/environments/environments_ui_b2b.json b/atest/testdata/performance/resources/environments/environments_ui_b2b.json
new file mode 100644
index 0000000..e92e899
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_ui_b2b.json
@@ -0,0 +1,130 @@
+{
+ "environment":"ui_b2b",
+ "env":{
+ "yves_url":"http://yves.de.spryker.local/",
+ "yves_at_url":"http://yves.at.spryker.local/",
+ "zed_url":"http://backoffice.de.spryker.local/",
+ "mp_url":"http://mp.de.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_url":"http://mp.de.spryker.local/",
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "yves_dms_url":"http://yves.eu.spryker.local/",
+ "yves_at_dms_url":"http://yves.eu.spryker.local/AT/",
+ "zed_dms_url":"http://backoffice.eu.spryker.local/",
+ "mp_dms_url":"http://mp.eu.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_dms_url":"http://mp.eu.spryker.local/",
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user_email":"sonia@spryker.com",
+ "yves_user_first_name":"Sonia",
+ "yves_user_last_name":"Wagner",
+ "yves_user_password":"change123",
+ "yves_company_user_manager_and_buyer_email":"andrew@ottom.de",
+ "yves_spryker_admin_company_user_email":"Solomon@spryker.com",
+ "yves_company_user_manager_and_buyer_firstname":"Andrew",
+ "yves_company_user_manager_and_buyer_lastname":"Wedner",
+ "yves_company_user_manager_and_buyer_address":"Mr Andrew Wedner, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_approver_email":"Lilu@ottom.de",
+ "yves_company_user_approver_firstname":"Lilu",
+ "yves_company_user_approver_lastname":"Dallas",
+ "yves_company_user_shared_permission_owner_email":"andrew@ottom.de",
+ "yves_company_user_shared_permission_owner_firstname":"Andrew",
+ "yves_company_user_shared_permission_owner_lastname":"Wedner",
+ "yves_company_user_shared_permission_owner_address":"Mr Andrew Wedner, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_shared_permission_receiver_email":"sally@ottom.de",
+ "yves_company_user_shared_permission_receiver_firstname":"Sally",
+ "yves_company_user_shared_permission_receiver_lastname":"Koval",
+ "yves_company_user_shared_permission_receiver_address":"Ms Sally Koval, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_buyer_with_limit_email":"sally@ottom.de",
+ "yves_company_user_buyer_with_limit_firstname":"Sally",
+ "yves_company_user_buyer_with_limit_lastname":"Koval",
+ "yves_company_user_buyer_with_limit_address":"Ms Sally Koval, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_buyer_email":"Richi@spryker.com",
+ "yves_company_user_buyer_reference":"DE--15",
+ "yves_company_user_buyer_firstname":"Armando",
+ "yves_company_user_buyer_lastname":"Richi",
+ "yves_company_user_buyer_address":"Mr Armando Richi, Gurmont Str. 23, 8002 Barcelona",
+ "yves_company_user_special_prices_customer_email":"Elizabet@spryker.com",
+ "yves_company_user_special_prices_customer_firstname":"Elizabet",
+ "yves_company_user_special_prices_customer_lastname":"Keller",
+ "yves_company_user_restriction_customer_email_1":"Frida@ottom.de",
+ "yves_company_user_restriction_customer_email_2":"Alexa@ottom.de",
+ "yves_company_user_bob_email":"donald@spryker.com",
+ "zed_admin_email":"admin@spryker.com",
+ "zed_admin_password":"change123"
+ },
+ "user_role":{
+ "bundle_access":"product-attribute-gui",
+ "controller_access":"attribute",
+ "action_access":"create",
+ "permission_allow":"allow",
+ "permission_deny":"deny",
+ "full_access":"*"
+ },
+ "glossary":{
+ "glossary_name":"customer.account.overview",
+ "original_EN_text":"Overview",
+ "original_DE_text":"Übersicht"
+ },
+ "products":{
+ "one_variant_product_abstract_sku":"M70208",
+ "one_variant_product_abstract_name":"EUROKRAFT trolley - with open shovel",
+ "one_variant_product_concrete_sku":"403125",
+ "one_variant_product_default_price":"€235.43",
+ "one_variant_product_merchant_price":"€188.34",
+ "concrete_avaiable_product_sku":"100414",
+ "concrete_avaiable_product_name":"Topstar executive chair - black leather - armrests with leather cover",
+ "concrete_avaiable_product_price":"335.13",
+ "stock_product_abstract_sku":"M1028702",
+ "stock_product_concrete_sku":"573330",
+ "multi_variant_product_abstract_sku":"M58035",
+ "multi_color_product_abstract_sku":"M12655",
+ "measurement_unit_product_abstract_sku":"M23723",
+ "packaging_unit_product_abstract_sku":"M21766",
+ "product_with_relations_related_products_sku":"M29529",
+ "product_with_relations_upselling_sku":"M29502",
+ "bundle_product_abstract_sku":"B0001",
+ "bundle_product_concrete_sku":"000101",
+ "bundled_product_1_abstract_sku":"M528",
+ "bundled_product_2_abstract_sku":"M1017905",
+ "bundled_product_3_abstract_sku":"M24605",
+ "bundled_product_1_concrete_sku":"104939",
+ "bundled_product_2_concrete_sku":"574995",
+ "bundled_product_3_concrete_sku":"426581",
+ "configurable_product_abstract_sku": "M636",
+ "configurable_product_concrete_sku": "574601",
+ "configurable_product_name": "CP steel cabinet, fire-resistant - 3 adjustable shelves - 1 locker - black gray / light gray",
+ "configurable_product_concrete_price": "1,826.54"
+ },
+ "misc":{
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "default_address":{
+ "salutation":"Mr",
+ "first_name":"RobotF",
+ "last_name":"RobotL",
+ "street":"Kirncher Str.",
+ "house_number":"7",
+ "post_code":"10247",
+ "city":"Berlin",
+ "country":"Germany",
+ "full_address":"Mr RobotF RobotL, Kirncher Str. 7, 10247 Berlin"
+ }
+ }
+ }
diff --git a/atest/testdata/performance/resources/environments/environments_ui_b2c.json b/atest/testdata/performance/resources/environments/environments_ui_b2c.json
new file mode 100644
index 0000000..a2b2ec8
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_ui_b2c.json
@@ -0,0 +1,209 @@
+{
+ "environment":"ui_b2c",
+ "env":{
+ "yves_url":"http://yves.de.spryker.local/",
+ "yves_at_url":"http://yves.at.spryker.local/",
+ "zed_url":"http://backoffice.de.spryker.local/",
+ "mp_url":"http://mp.de.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_url":"http://mp.de.spryker.local/",
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "yves_dms_url":"http://yves.eu.spryker.local/",
+ "yves_at_dms_url":"http://yves.eu.spryker.local/AT/",
+ "zed_dms_url":"http://backoffice.eu.spryker.local/",
+ "mp_dms_url":"http://mp.eu.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_dms_url":"http://mp.eu.spryker.local/",
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user_email":"george.freeman@spryker.com",
+ "yves_user_first_name":"George",
+ "yves_user_last_name":"Freeman",
+ "yves_user_password":"change123",
+ "yves_user_reference":"DE--5",
+ "yves_user_salutation":"Mr",
+ "yves_user_address":"Mr George Freeman, Kirncher Str. 7, 10247 Berlin",
+ "yves_second_user_email":"bill.martin@spryker.com",
+ "yves_second_user_first_name":"Bill",
+ "yves_second_user_last_name":"Martin",
+ "yves_second_user_password":"change123",
+ "zed_admin_email":"admin@spryker.com",
+ "zed_admin_email_de":"admin_de@spryker.com",
+ "zed_admin_password":"change123"
+ },
+ "user_role":{
+ "bundle_access":"product-attribute-gui",
+ "controller_access":"attribute",
+ "action_access":"create",
+ "permission_allow":"allow",
+ "permission_deny":"deny",
+ "full_access":"*"
+ },
+ "glossary":{
+ "glossary_name":"customer.account.overview",
+ "original_EN_text":"Overview",
+ "original_DE_text":"Übersicht"
+ },
+ "products":{
+ "one_variant_product_abstract_sku":"009",
+ "one_variant_product_abstract_name":"EUROKRAFT trolley - with open shovel",
+ "one_variant_product_default_price":"€99.99",
+ "one_variant_product_concrete_sku":"009_30692991",
+ "bundle_product_abstract_sku":"211",
+ "bundle_product_product_name":"HP Bundle",
+ "bundled_product_1_abstract_sku":"121",
+ "bundled_product_2_abstract_sku":"127",
+ "bundled_product_3_abstract_sku":"150",
+ "bundled_product_1_concrete_sku":"121_29406823",
+ "bundled_product_2_concrete_sku":"127_22828284",
+ "bundled_product_3_concrete_sku":"150_29554292",
+ "multi_variant_product_abstract_sku":"051",
+ "measurement_unit_product_abstract_sku":"215",
+ "packaging_unit_product_abstract_sku":"218",
+ "product_with_relations_related_products_sku":"200",
+ "product_with_relations_alternative_products_sku":"145",
+ "product_with_relations_upselling_sku":"018",
+ "stock_product_abstract_sku": "063",
+ "stock_product_concrete_sku": "063_29231675",
+ "discontinued_product_abstract_sku": "016",
+ "discontinued_product_concrete_sku": "016_21748907",
+ "configurable_product_abstract_sku": "124",
+ "configurable_product_concrete_one_sku": "124_31623088",
+ "configurable_product_concrete_one_attribute": "128 GB",
+ "configurable_product_concrete_two_sku": "124_29866591",
+ "configurable_product_concrete_two_attribute": "500 GB",
+ "configurable_product_name": "HP ProDesk 400 G3",
+ "configurable_product_concrete_one_price": "25.00",
+ "configurable_product_concrete_two_price": "310.19"
+ },
+ "address":{
+ "street_name":"st",
+ "city":"Berlin",
+ "country":"Germany",
+ "additional_address":"additional street",
+ "company":"spryker"
+ },
+ "address_api":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"False",
+ "billing_status":"False"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ }
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ }
+ },
+ "guest_user":{
+ "salutation":"Mr.",
+ "guest_user_first_name":"Guest",
+ "guest_user_last_name":"martin"
+ },
+ "misc":{
+ "order_state":"New",
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded",
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "default_address":{
+ "salutation":"Mr",
+ "first_name":"RobotF",
+ "last_name":"RobotL",
+ "street":"Kirncher Str.",
+ "house_number":"7",
+ "post_code":"10247",
+ "city":"Berlin",
+ "country":"Germany",
+ "full_address":"Mr RobotF RobotL, Kirncher Str. 7, 10247 Berlin"
+ }
+ }
+ ,
+ "payment":{
+ "payment_provider_name":"dummyMarketplacePayment",
+ "payment_method_name":"Invoice",
+ "payment_selection_name":"dummyMarketplacePaymentInvoice",
+ "payment_provider_name_1":"DummyPayment",
+ "payment_method_name_1":"Credit Card"
+ },
+ "warehouse_user_assignment":{
+ "warehouse_user":[
+ {
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f"
+ }],
+ "warehouse":[
+ {
+ "warehouse_uuid":"8e5f7bf2-ab97-595c-9b42-487392e2af9b",
+ "warehouse_uuid_budjet_cameras":"5bf5cc56-a50b-5029-9011-feeed83af180",
+ "warehouse_name":"Spryker MER000001 Warehouse 1",
+ "warehouse_uuid_warehouse1":"834b3731-02d4-5d6f-9a61-d63ae5e70517",
+ "warehouse_name_budjet_cameras":"Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid":"86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "video_king_warehouse_name":"Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker":"4"
+ }]
+ }
+ }
+
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/environments/environments_ui_mp_b2b.json b/atest/testdata/performance/resources/environments/environments_ui_mp_b2b.json
new file mode 100644
index 0000000..6fada99
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_ui_mp_b2b.json
@@ -0,0 +1,140 @@
+{
+ "environment":"ui_mp_b2b",
+ "env":{
+ "yves_url":"http://yves.de.spryker.local/",
+ "yves_at_url":"http://yves.at.spryker.local/",
+ "zed_url":"http://backoffice.de.spryker.local/",
+ "mp_url":"http://mp.de.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_url":"http://mp.de.spryker.local/",
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "yves_dms_url":"http://yves.eu.spryker.local/",
+ "yves_at_dms_url":"http://yves.eu.spryker.local/AT/",
+ "zed_dms_url":"http://backoffice.eu.spryker.local/",
+ "mp_dms_url":"http://mp.eu.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_dms_url":"http://mp.eu.spryker.local/",
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user_email":"sonia@spryker.com",
+ "yves_user_first_name":"Sonia",
+ "yves_user_last_name":"Wagner",
+ "yves_user_password":"change123",
+ "yves_company_user_manager_and_buyer_email":"andrew@ottom.de",
+ "yves_company_user_manager_and_buyer_firstname":"Andrew",
+ "yves_company_user_manager_and_buyer_lastname":"Wedner",
+ "yves_company_user_manager_and_buyer_address":"Mr Andrew Wedner, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_approver_email":"Lilu@ottom.de",
+ "yves_company_user_approver_firstname":"Lilu",
+ "yves_company_user_approver_lastname":"Dallas",
+ "yves_company_user_shared_permission_owner_email":"andrew@ottom.de",
+ "yves_company_user_shared_permission_owner_firstname":"Andrew",
+ "yves_company_user_shared_permission_owner_lastname":"Wedner",
+ "yves_company_user_shared_permission_owner_address":"Mr Andrew Wedner, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_shared_permission_receiver_email":"sally@ottom.de",
+ "yves_company_user_shared_permission_receiver_firstname":"Sally",
+ "yves_company_user_shared_permission_receiver_lastname":"Koval",
+ "yves_company_user_shared_permission_receiver_address":"Ms Sally Koval, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_buyer_with_limit_email":"sally@ottom.de",
+ "yves_company_user_buyer_with_limit_firstname":"Sally",
+ "yves_company_user_buyer_with_limit_lastname":"Koval",
+ "yves_company_user_buyer_with_limit_address":"Ms Sally Koval, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_buyer_email":"Richi@spryker.com",
+ "yves_company_user_buyer_firstname":"Armando",
+ "yves_company_user_buyer_lastname":"Richi",
+ "yves_company_user_buyer_reference":"DE--15",
+ "yves_company_user_buyer_address":"Mr Armando Richi, Gurmont Str. 23, 8002 Barcelona",
+ "yves_company_user_special_prices_customer_email":"Elizabet@spryker.com",
+ "yves_company_user_special_prices_customer_firstname":"Elizabet",
+ "yves_company_user_special_prices_customer_lastname":"Keller",
+ "yves_company_user_restriction_customer_email_1":"Frida@ottom.de",
+ "yves_company_user_restriction_customer_email_2":"Alexa@ottom.de",
+ "yves_company_user_bob_email":"donald@spryker.com",
+ "yves_company_user_custom_merchant_prices_email":"Solomon@spryker.com",
+ "yves_spryker_admin_company_user_email":"Solomon@spryker.com",
+ "zed_admin_email":"admin@spryker.com",
+ "zed_admin_password":"change123",
+ "zed_main_merchant_email":"richard@spryker.com",
+ "merchant_office_king_email":"martha@office-king.nl",
+ "merchant_office_king_reference":"MER000009",
+ "merchant_computer_experts_email":"michele@computer-experts.com",
+ "merchant_spryker_email":"harald@spryker.com",
+ "merchant_spryker_reference":"MER000008"
+ },
+ "user_role":{
+ "bundle_access":"product-attribute-gui",
+ "controller_access":"attribute",
+ "action_access":"create",
+ "permission_allow":"allow",
+ "permission_deny":"deny",
+ "full_access":"*"
+ },
+ "glossary":{
+ "glossary_name":"customer.account.overview",
+ "original_EN_text":"Overview",
+ "original_DE_text":"Übersicht"
+ },
+ "products":{
+ "one_variant_product_abstract_sku":"M70208",
+ "one_variant_product_abstract_name":"EUROKRAFT trolley - with open shovel",
+ "one_variant_product_default_price":"€235.43",
+ "one_variant_product_merchant_price":"€188.34",
+ "one_variant_product_concrete_sku":"403125",
+ "one_variant_product_of_main_merchant_abstract_sku":"M1024684",
+ "one_variant_product_of_main_merchant_abstract_name":"Mauser sliding door cabinet - with glass front, 4 shelves",
+ "one_variant_product_of_main_merchant_abstract_price":"€632.12",
+ "one_variant_product_of_main_merchant_concrete_sku":"410090",
+ "product_with_multiple_offers_abstract_sku":"M25600",
+ "product_with_multiple_offers_concrete_sku":"427915",
+ "product_with_multiple_offers_computer_experts_price":"€15.93",
+ "product_with_multiple_offers_office_king_price":"€16.81",
+ "multi_variant_product_abstract_sku":"M58035",
+ "multi_color_product_abstract_sku":"M12655",
+ "measurement_unit_product_abstract_sku":"M23723",
+ "packaging_unit_product_abstract_sku":"M21766",
+ "product_with_relations_related_products_sku":"M29529",
+ "product_with_relations_upselling_sku":"M29502",
+ "volume_prices_product_abstract_sku":"M21189",
+ "volume_prices_product_concrete_sku":"420685",
+ "stock_product_abstract_sku": "M72935",
+ "stock_product_concrete_sku": "103907",
+ "discontinued_product_abstract_sku": "M5108",
+ "discontinued_product_concrete_sku": "400065",
+ "configurable_product_abstract_sku": "M636",
+ "configurable_product_concrete_sku": "574601",
+ "configurable_product_name": "CP steel cabinet, fire-resistant - 3 adjustable shelves - 1 locker - black gray / light gray",
+ "configurable_product_concrete_price": "1,826.54",
+ "product_with_never_out_of_stock_offer_abstract_sku": "M23729",
+ "product_with_never_out_of_stock_offer_concrete_sku": "425087"
+ },
+ "misc":{
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "default_address":{
+ "salutation":"Mr",
+ "first_name":"RobotF",
+ "last_name":"RobotL",
+ "street":"Kirncher Str.",
+ "house_number":"7",
+ "post_code":"10247",
+ "city":"Berlin",
+ "country":"Germany",
+ "full_address":"Mr RobotF RobotL, Kirncher Str. 7, 10247 Berlin"
+ }
+ }
+ }
diff --git a/atest/testdata/performance/resources/environments/environments_ui_mp_b2c.json b/atest/testdata/performance/resources/environments/environments_ui_mp_b2c.json
new file mode 100644
index 0000000..e0d2641
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_ui_mp_b2c.json
@@ -0,0 +1,239 @@
+{
+ "environment":"ui_mp_b2c",
+ "env":{
+ "yves_url":"http://yves.de.spryker.local/",
+ "yves_at_url":"http://yves.at.spryker.local/",
+ "zed_url":"http://backoffice.de.spryker.local/",
+ "mp_url":"http://mp.de.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_url":"http://mp.de.spryker.local/",
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local",
+ "sapi_url":"http://glue-storefront.de.spryker.local"
+ },
+ "dms_env":{
+ "yves_dms_url":"http://yves.eu.spryker.local/",
+ "zed_dms_url":"http://backoffice.eu.spryker.local/",
+ "yves_at_dms_url":"http://yves.eu.spryker.local/AT/",
+ "mp_dms_url":"http://mp.eu.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_dms_url":"http://mp.eu.spryker.local/",
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env": "5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user_email":"george.freeman@spryker.com",
+ "yves_user_first_name":"George",
+ "yves_user_salutation":"Mr",
+ "yves_user_last_name":"Freeman",
+ "yves_user_password":"change123",
+ "yves_user_reference":"DE--5",
+ "yves_user_address":"Mr George Freeman, Kirncher Str. 7, 10247 Berlin",
+ "yves_second_user_email":"bill.martin@spryker.com",
+ "yves_second_user_first_name":"Bill",
+ "yves_second_user_last_name":"Martin",
+ "yves_second_user_password":"change123",
+ "zed_admin_email":"admin@spryker.com",
+ "zed_admin_password":"change123",
+ "zed_admin_email_de":"admin_de@spryker.com",
+ "zed_main_merchant_email":"richard@spryker.com",
+ "merchant_budget_cameras_email":"jason.weidmann@budgetcamerasonline.com",
+ "merchant_budget_cameras_reference":"MER000005",
+ "merchant_video_king_email":"martha@video-king.nl",
+ "merchant_spryker_email":"harald@spryker.com",
+ "merchant_spryker_reference":"MER000001"
+ },
+ "user_role":{
+ "bundle_access":"product-attribute-gui",
+ "controller_access":"attribute",
+ "action_access":"create",
+ "permission_allow":"allow",
+ "permission_deny":"deny",
+ "full_access":"*"
+ },
+ "glossary":{
+ "glossary_name":"customer.account.overview",
+ "original_EN_text":"Overview",
+ "original_DE_text":"Übersicht"
+ },
+ "products":{
+ "one_variant_product_abstract_sku":"009",
+ "one_variant_product_abstract_name":"EUROKRAFT trolley - with open shovel",
+ "one_variant_product_default_price":"€99.99",
+ "one_variant_product_concrete_sku":"009_30692991",
+ "one_variant_product_of_main_merchant_abstract_sku":"064",
+ "one_variant_product_of_main_merchant_abstract_name":"Samsung Galaxy S4 Mini",
+ "one_variant_product_of_main_merchant_abstract_price":"€54.48",
+ "one_variant_product_of_main_merchant_concrete_sku":"064_18404924",
+ "product_with_multiple_offers_abstract_sku":"041",
+ "product_with_multiple_offers_abstract_name":"Canon PowerShot SX610",
+ "product_with_multiple_offers_concrete_sku":"041_25904691",
+ "product_with_multiple_offers_budget_cameras_price":"€93.42",
+ "product_with_multiple_offers_video_king_price":"€98.61",
+ "second_product_with_multiple_offers_abstract_sku":"023",
+ "second_product_with_multiple_offers_abstract_name":"Sony Cyber-shot DSC-WX220",
+ "second_product_with_multiple_offers_concrete_sku":"023_21758366",
+ "second_product_with_multiple_offers_budget_cameras_price":"€240.51",
+ "second_product_with_multiple_offers_video_king_price":"€253.87",
+ "second_product_with_multiple_offers_sony_experts_price":"€227.15",
+ "bundle_product_abstract_sku":"211",
+ "bundle_product_product_name":"HP Bundle",
+ "bundled_product_1_abstract_sku":"121",
+ "bundled_product_1_abstract_name":"HP 200 280 G1",
+ "bundled_product_2_abstract_sku":"127",
+ "bundled_product_2_abstract_name":"HP Z 620",
+ "bundled_product_3_abstract_sku":"150",
+ "bundled_product_3_abstract_name":"HP Chromebook 11",
+ "bundled_product_1_concrete_sku":"121_29406823",
+ "bundled_product_1_concrete_name":"HP 200 280 G1",
+ "bundled_product_2_concrete_sku":"127_22828284",
+ "bundled_product_2_concrete_name":"HP Z 620",
+ "bundled_product_3_concrete_sku":"150_29554292",
+ "bundled_product_3_concrete_name":"HP Chromebook 11",
+ "multi_variant_product_abstract_sku":"051",
+ "measurement_unit_product_abstract_sku":"215",
+ "packaging_unit_product_abstract_sku":"218",
+ "product_with_relations_related_products_sku":"149",
+ "product_with_relations_alternative_products_sku":"145",
+ "product_with_relations_upselling_sku":"018",
+ "stock_product_abstract_sku": "208",
+ "stock_product_concrete_sku": "208_14678762",
+ "discontinued_product_abstract_sku": "172",
+ "discontinued_product_concrete_sku": "172_29801891",
+ "configurable_product_abstract_sku": "124",
+ "configurable_product_concrete_one_sku": "124_31623088",
+ "configurable_product_concrete_one_attribute": "128 GB",
+ "configurable_product_concrete_two_sku": "124_29866591",
+ "configurable_product_concrete_two_attribute": "500 GB",
+ "configurable_product_name": "HP ProDesk 400 G3",
+ "configurable_product_concrete_one_price": "25.00",
+ "configurable_product_concrete_two_price": "310.19",
+ "product_with_never_out_of_stock_offer_abstract_sku": "040",
+ "product_with_never_out_of_stock_offer_concrete_sku": "040_25904665"
+ },
+ "misc":{
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ },
+ "default_address":{
+ "salutation":"Mr",
+ "first_name":"RobotF",
+ "last_name":"RobotL",
+ "street":"Kirncher Str.",
+ "house_number":"7",
+ "post_code":"10247",
+ "city":"Berlin",
+ "country":"Germany",
+ "full_address":"Mr RobotF RobotL, Kirncher Str. 7, 10247 Berlin"
+ }
+ },
+ "address":{
+ "street_name":"st",
+ "city":"Berlin",
+ "country":"Germany",
+ "additional_address":"additional street",
+ "company":"spryker"
+ },
+ "address_api":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"False",
+ "billing_status":"False"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ }
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ }
+ },
+ "guest_user":{
+ "salutation":"Mr.",
+ "guest_user_first_name":"Guest",
+ "guest_user_last_name":"martin"
+ },
+ "other":{
+ "order_state":"New",
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded"
+ },
+ "payment":{
+ "payment_provider_name":"dummyMarketplacePayment",
+ "payment_method_name":"Invoice",
+ "payment_selection_name":"dummyMarketplacePaymentInvoice",
+ "payment_provider_name_1":"DummyPayment",
+ "payment_method_name_1":"Credit Card"
+ },
+ "warehouse_user_assignment":{
+ "warehouse_user":[
+ {
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f"
+ }],
+ "warehouse":[
+ {
+ "warehouse_uuid":"e84b3cb8-a94a-5a7e-9adb-cc5353f7a73f",
+ "warehouse_uuid_budjet_cameras":"5bf5cc56-a50b-5029-9011-feeed83af180",
+ "warehouse_name":"Spryker MER000001 Warehouse 1",
+ "warehouse_uuid_warehouse1":"834b3731-02d4-5d6f-9a61-d63ae5e70517",
+ "warehouse_name_budjet_cameras":"Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid":"86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "video_king_warehouse_name":"Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker":"4"
+ }]
+}
+}
+
diff --git a/atest/testdata/performance/resources/environments/environments_ui_suite.json b/atest/testdata/performance/resources/environments/environments_ui_suite.json
new file mode 100644
index 0000000..7c34589
--- /dev/null
+++ b/atest/testdata/performance/resources/environments/environments_ui_suite.json
@@ -0,0 +1,279 @@
+{
+ "environment":"ui_suite",
+ "env":{
+ "yves_url":"http://yves.de.spryker.local/",
+ "yves_at_url":"http://yves.at.spryker.local/",
+ "zed_url":"http://backoffice.de.spryker.local/",
+ "mp_url":"http://mp.de.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_url":"http://mp.de.spryker.local/",
+ "glue_url":"http://glue.de.spryker.local",
+ "bapi_url":"http://glue-backend.de.spryker.local"
+ },
+ "dms_env":{
+ "yves_dms_url":"http://yves.eu.spryker.local/",
+ "yves_at_dms_url":"http://yves.eu.spryker.local/AT/",
+ "zed_dms_url":"http://backoffice.eu.spryker.local/",
+ "mp_dms_url":"http://mp.eu.spryker.local/security-merchant-portal-gui/login/",
+ "mp_root_dms_url":"http://mp.eu.spryker.local/",
+ "glue_dms_url":"http://glue.eu.spryker.local",
+ "bapi_dms_url":"http://glue-backend.eu.spryker.local",
+ "sapi_dms_url":"http://glue-storefront.eu.spryker.local"
+ },
+ "database":{
+ "db_host":"127.0.0.1",
+ "db_port_env":"3306",
+ "db_port_postgres_env":"5432",
+ "db_user":"spryker",
+ "db_password":"secret",
+ "db_name":"eu-docker"
+ },
+ "users":{
+ "yves_user_email":"george.freeman@spryker.com",
+ "yves_user_first_name":"George",
+ "yves_user_salutation":"Mr",
+ "yves_user_last_name":"Freeman",
+ "yves_user_password":"change123",
+ "yves_user_reference":"DE--5",
+ "yves_user_address":"Mr George Freeman, Kirncher Str. 7, 10247 Berlin",
+ "yves_second_user_email":"bill.martin@spryker.com",
+ "yves_second_user_first_name":"Bill",
+ "yves_second_user_last_name":"Martin",
+ "yves_second_user_password":"change123",
+ "yves_test_company_user_email":"spencor.hopkin@spryker.com",
+ "yves_test_company_user_first_name":"Spencor",
+ "yves_test_company_user_last_name":"Hopkin",
+ "yves_test_company_user_password":"change123",
+ "yves_test_company_user_reference":"DE--1",
+ "yves_default_user_email":"sonia@spryker.com",
+ "yves_default_user_address":"Ms Sonia Wagner, Kirncher Str. 7, 10247 Berlin",
+ "zed_admin_email":"admin@spryker.com",
+ "zed_admin_password":"change123",
+ "zed_admin_email_de":"admin_de@spryker.com",
+ "zed_main_merchant_email":"richard@spryker.com",
+ "merchant_budget_cameras_email":"jason.weidmann@budgetcamerasonline.com",
+ "merchant_budget_cameras_reference":"MER000005",
+ "merchant_video_king_email":"martha@video-king.nl",
+ "merchant_spryker_email":"harald@spryker.com",
+ "merchant_spryker_reference":"MER000001",
+ "merchant_sony_experts_email":"michele@sony-experts.com",
+ "merchant_sony_experts_reference":"MER000006",
+ "yves_company_user_shared_permission_owner_email":"andrew@ottom.de",
+ "yves_spryker_admin_company_user_email":"Solomon@spryker.com",
+ "yves_company_user_shared_permission_owner_firstname":"Andrew",
+ "yves_company_user_shared_permission_owner_lastname":"Wedner",
+ "yves_company_user_shared_permission_owner_address":"Mr Andrew Wedner, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_shared_permission_receiver_email":"sally@ottom.de",
+ "yves_company_user_shared_permission_receiver_firstname":"Sally",
+ "yves_company_user_shared_permission_receiver_lastname":"Koval",
+ "yves_company_user_shared_permission_receiver_address":"Ms Sally Koval, Seeburger Str. 270, 10115 Berlin",
+ "yves_company_user_buyer_email":"Richi@spryker.com",
+ "yves_company_user_buyer_reference":"DE--15",
+ "yves_company_user_buyer_firstname":"Armando",
+ "yves_company_user_buyer_lastname":"Richi",
+ "yves_company_user_buyer_address":"Mr Armando Richi, Gurmont Str. 23, 8002 Barcelona",
+ "yves_company_user_blacklist_restriction_customer_email":"frida@ottom.de",
+ "yves_company_user_blacklist_restriction_customer_first_name":"Frida",
+ "yves_company_user_blacklist_restriction_customer_last_name":"Grott",
+ "yves_company_user_blacklist_restriction_customer_company":"Ottom ltd",
+ "yves_company_user_blacklist_restriction_customer_bu":"Ottom store Berlin (id: 20)",
+ "yves_company_user_whotelist_restriction_customer_email":"alexa@ottom.de",
+ "yves_company_user_bob_email":"donald@spryker.com"
+ },
+ "user_role":{
+ "bundle_access":"product-attribute-gui",
+ "controller_access":"attribute",
+ "action_access":"create",
+ "permission_allow":"allow",
+ "permission_deny":"deny",
+ "full_access":"*"
+ },
+ "glossary":{
+ "glossary_name":"customer.account.overview",
+ "original_EN_text":"Overview",
+ "original_DE_text":"Übersicht"
+ },
+ "products":{
+ "one_variant_product_abstract_sku":"009",
+ "one_variant_product_concrete_sku":"009_30692991",
+ "product_with_merchant_price_abstract_sku":"205",
+ "product_with_merchant_price_concrete_sku":"205_6350138",
+ "product_with_merchant_price_product_name":"Toshiba CAMILEO S30",
+ "product_with_merchant_price_default_price":"€116.11",
+ "product_with_merchant_price_merchant_price":"€100.22",
+ "one_variant_product_of_main_merchant_abstract_sku":"064",
+ "one_variant_product_of_main_merchant_abstract_name":"Samsung Galaxy S4 Mini",
+ "one_variant_product_of_main_merchant_abstract_price":"€54.48",
+ "one_variant_product_of_main_merchant_concrete_sku":"064_18404924",
+ "volume_prices_product_abstract_sku":"041",
+ "volume_prices_product_concrete_sku":"041_25904691",
+ "volume_prices_product_name":"Canon PowerShot SX610",
+ "product_with_multiple_offers_abstract_sku":"041",
+ "product_with_multiple_offers_abstract_name":"Canon PowerShot SX610",
+ "product_with_multiple_offers_concrete_sku":"041_25904691",
+ "product_with_multiple_offers_budget_cameras_price":"€93.42",
+ "product_with_multiple_offers_video_king_price":"€98.61",
+ "second_product_with_multiple_offers_abstract_sku":"023",
+ "second_product_with_multiple_offers_abstract_name":"Sony Cyber-shot DSC-WX220",
+ "second_product_with_multiple_offers_concrete_sku":"023_21758366",
+ "second_product_with_multiple_offers_budget_cameras_price":"€240.51",
+ "second_product_with_multiple_offers_video_king_price":"€253.87",
+ "second_product_with_multiple_offers_sony_experts_price":"€227.15",
+ "second_product_with_multiple_offers_spryker_price":"€267.23",
+ "product_with_budget_cameras_offer_abstract_sku":"004",
+ "product_with_budget_cameras_offer_concrete_sku":"004_30663302",
+ "product_with_sony_experts_offer_abstract_sku":"024",
+ "product_with_sony_experts_offer_concrete_sku":"024_21987578",
+ "bundle_product_abstract_sku":"211",
+ "bundle_product_concrete_sku":"211_123",
+ "bundle_product_product_name":"HP Bundle",
+ "bundled_product_1_abstract_sku":"121",
+ "bundled_product_2_abstract_sku":"127",
+ "bundled_product_3_abstract_sku":"150",
+ "bundled_product_1_concrete_sku":"121_29406823",
+ "bundled_product_2_concrete_sku":"127_22828284",
+ "bundled_product_3_concrete_sku":"150_29554292",
+ "multi_variant_product_abstract_sku":"051",
+ "measurement_unit_product_abstract_sku":"215",
+ "packaging_unit_product_abstract_sku":"218",
+ "product_with_relations_related_products_sku":"149",
+ "product_with_relations_alternative_products_sku":"145",
+ "product_with_relations_upselling_sku":"018",
+ "stock_product_abstract_sku":"208",
+ "stock_product_concrete_sku":"208_14678762",
+ "discontinued_product_abstract_sku":"172",
+ "discontinued_product_concrete_sku":"172_29801891",
+ "configurable_product_abstract_sku":"093",
+ "configurable_product_concrete_sku":"093_24495843",
+ "configurable_product_price":"248.99",
+ "configurable_product_price_with_options":"€664.50",
+ "configurable_product_price_without_configurations":"€248.99",
+ "configurable_product_name":"Sony SmartWatch 3",
+ "available_never_out_of_stock_abstract_sku":"007",
+ "available_never_out_of_stock_concrete_sku":"007_30691822",
+ "available_never_out_of_stock_abstract_name":"Canon IXUS 285",
+ "product_with_sale_price_abstract_sku":"006",
+ "product_with_sale_price_concrete_sku":"006_30692993",
+ "product_with_sale_price_abstract_name":"Canon IXUS 175",
+ "product_with_never_out_of_stock_offer_abstract_sku": "040",
+ "product_with_never_out_of_stock_offer_concrete_sku": "040_25904665"
+ },
+ "misc":{
+ "grant_type":{
+ "password":"password",
+ "refresh_token":"refresh_token"
+ }
+ },
+ "address":{
+ "street_name":"st",
+ "city":"Berlin",
+ "country":"Germany",
+ "additional_address":"additional street",
+ "company":"spryker",
+ "default_address":{
+ "salutation":"Mr",
+ "first_name":"RobotF",
+ "last_name":"RobotL",
+ "street":"Kirncher Str.",
+ "house_number":"7",
+ "post_code":"10247",
+ "city":"Berlin",
+ "country":"Germany",
+ "full_address":"Mr RobotF RobotL, Kirncher Str. 7, 10247 Berlin"
+ }
+ },
+ "address_api":{
+ "default":{
+ "address1":"Third, 33, 11",
+ "address2":"33-B",
+ "address3":"third. address. line",
+ "zipCode":"12312",
+ "city":"Berlin",
+ "country":"Germany",
+ "iso2Code":"DE",
+ "company":"Spryker",
+ "phone":"22111-3-4-5",
+ "shipping_status":"False",
+ "billing_status":"False"
+ },
+ "changed":{
+ "address1":"New Street 123",
+ "address2":"75d",
+ "address3":"third. address. line - changed",
+ "phone":"555-555-55"
+ }
+ },
+ "shop":{
+ "currency":{
+ "eur":{
+ "name":"Euro",
+ "code":"EUR",
+ "symbol":"€"
+ },
+ "chf":{
+ "name":"Swiss Franc",
+ "code":"CHF",
+ "symbol":"CHF"
+ },
+ "dollar":{
+ "name":"US Dollar",
+ "code":"USD",
+ "symbol":"$"
+ }
+ },
+ "locale":{
+ "DE":{
+ "name":"de_DE",
+ "code":"de"
+ },
+ "EN":{
+ "name":"en_US",
+ "code":"en"
+ }
+ },
+ "mode":{
+ "gross":"GROSS_MODE",
+ "net":"NET_MODE"
+ },
+ "store":{
+ "us":"US",
+ "de":"DE"
+ }
+ },
+ "guest_user":{
+ "salutation":"Mr.",
+ "guest_user_first_name":"Guest",
+ "guest_user_last_name":"martin"
+ },
+ "other":{
+ "order_state":"New",
+ "default_header_content_type":"application/vnd.api+json",
+ "urlencoded_header_content_type":"application/x-www-form-urlencoded"
+ },
+ "payment":{
+ "payment_provider_name":"dummyMarketplacePayment",
+ "payment_method_name":"Invoice",
+ "payment_selection_name":"dummyMarketplacePaymentInvoice",
+ "payment_provider_name_1":"DummyPayment",
+ "payment_method_name_1":"Credit Card"
+ },
+ "warehouse_user_assignment":{
+ "warehouse_user":[
+ {
+ "admin_user_uuid":"c0e244d4-03e8-556f-aa8d-174be9d236e5",
+ "de_admin_user_uuid":"92cd431f-96e3-5259-91cb-ab9f6d14829f"
+ }
+ ],
+ "warehouse":[
+ {
+ "warehouse_uuid":"e84b3cb8-a94a-5a7e-9adb-cc5353f7a73f",
+ "warehouse_uuid_budjet_cameras":"5bf5cc56-a50b-5029-9011-feeed83af180",
+ "warehouse_name":"Spryker MER000001 Warehouse 1",
+ "warehouse_uuid_warehouse1":"834b3731-02d4-5d6f-9a61-d63ae5e70517",
+ "warehouse_name_budjet_cameras":"Budget Cameras MER000005 Warehouse 1",
+ "video_king_warehouse_uuid":"86496ec7-0d44-518c-81e4-f472b9e8547d",
+ "video_king_warehouse_name":"Video King MER000002 Warehouse 1",
+ "fk_warehouse_spryker":"4"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/libraries/common.py b/atest/testdata/performance/resources/libraries/common.py
new file mode 100644
index 0000000..57f23b7
--- /dev/null
+++ b/atest/testdata/performance/resources/libraries/common.py
@@ -0,0 +1,54 @@
+"""A library for custom keywords
+"""
+import json
+import re
+
+def defineEnvironmentVariablesFromJsonFile(env):
+ print(f'Looking for {env} environment')
+ variables = {}
+ environments_file_path = 'resources/environments/environments_' + env + '.json'
+ try:
+ with open(environments_file_path) as json_file:
+ data = json.loads(json_file.read())
+ if data["environment"] == env:
+ print(f'Found an environment {env}!')
+ for key, value in data.items():
+ if type(value) == dict:
+ for key, value in value.items():
+ if key not in variables:
+ variables[key] = value
+ elif type(value) == str:
+ if key not in variables:
+ variables[key] = value
+ except:
+ print(f'Failed loading data for {env} environment!')
+ return variables
+
+
+def get_url_without_starting_slash(string):
+ if string[0] == "/":
+ string_without_starting_slash = string[1:]
+ return string_without_starting_slash
+ else:
+ return string
+
+def fill_variables_from_text_string(*args):
+ # the multi-line variable in a table form is splitted, keys are the 0 element and values are the 1st element.
+ #Both are just strings with | separators
+ arguments = ' '.join(args)
+ keys = (arguments.split(' || '))[0]
+ values = (arguments.split(' || '))[1]
+ # now the strings are splitted by "|" separator. Also strip() removes all whitespaces
+ keys_list = (keys.split('|'))
+ values_list = (values.split('|'))
+ dictionatry = dict()
+ for item in keys_list:
+ # 'if item' checks if the key value is not empty and iterates only over keys that have a value
+ if item:
+ # interate through all keys, get their indexes and assign to each a value with the same index and put them into disctionary
+ # strip() removed all whitespaces
+ key = item.strip()
+ index = keys_list.index(item)
+ value = values_list[index].strip()
+ dictionatry[key] = value
+ return dictionatry
diff --git a/atest/testdata/performance/resources/libraries/fastjson.py b/atest/testdata/performance/resources/libraries/fastjson.py
new file mode 100644
index 0000000..a9bfb95
--- /dev/null
+++ b/atest/testdata/performance/resources/libraries/fastjson.py
@@ -0,0 +1,16 @@
+
+def get_value(body, path):
+ """
+ body: Python dict
+ path: Robot-style "[data][0][attributes][name]"
+ """
+ # strip leading/trailing brackets & quotes, split on ']['
+ keys = path.strip("[]").split("][")
+ cur = body
+ for k in keys:
+ # numeric indices become ints
+ if k.isdigit():
+ cur = cur[int(k)]
+ else:
+ cur = cur[k]
+ return cur
diff --git a/atest/testdata/performance/resources/libraries/playwright/module.js b/atest/testdata/performance/resources/libraries/playwright/module.js
new file mode 100644
index 0000000..280d24a
--- /dev/null
+++ b/atest/testdata/performance/resources/libraries/playwright/module.js
@@ -0,0 +1,12 @@
+async function injectRequestApiIntoPage(page) {
+ return page.exposeFunction('_request', async function ({url, method, options}) {
+ const response = await page.request[method.toLowerCase()](url, options)
+ const data = {status: response.status(), body: await response.text(), headers: response.headers()}
+ response.dispose()
+
+ return data
+ })
+}
+
+exports.__esModule = true
+exports.injectRequestApiIntoPage = injectRequestApiIntoPage
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/apps/apps_payone_cc_payment_page.robot b/atest/testdata/performance/resources/pages/apps/apps_payone_cc_payment_page.robot
new file mode 100644
index 0000000..b517c43
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/apps/apps_payone_cc_payment_page.robot
@@ -0,0 +1,9 @@
+*** Variables ***
+${apps_payone_payment_cc_card_type} id=cardtype
+${apps_payone_payment_cc_name_on_card} id=cardholder
+${apps_payone_payment_cc_card_number} xpath=//div[@id='cardpan']//iframe >>> //input[@id='cardpan']
+${apps_payone_payment_cc_expire_year} xpath=//div[@id='cardexpireyear']//iframe >>> //select[@id='cardexpireyear']
+${apps_payone_payment_cc_expire_month} xpath=//div[@id='cardexpiremonth']//iframe >>> //select[@id='cardexpiremonth']
+${apps_payone_payment_cc_cvc} xpath=//div[@id='cardcvc2']//iframe >>> //input[@id='cardcvc2']
+${apps_payone_payment_pay_btn} id=paymentsubmit
+${apps_payone_payment_cancel_btn} xpath=//a[contains(@class, 'btn') and contains(text(), 'cancel')]
diff --git a/atest/testdata/performance/resources/pages/mp/mp_account_page.robot b/atest/testdata/performance/resources/pages/mp/mp_account_page.robot
new file mode 100644
index 0000000..ee7fbed
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_account_page.robot
@@ -0,0 +1,10 @@
+*** Variables ***
+${mp_my_account_header_menu_item} xpath=//spy-user-menu-link[@class='spy-user-menu-link'][normalize-space(text())='My Account']
+${mp_account_first_name_field} id=user-merchant-portal-gui_merchant-account_first_name
+${mp_account_last_name_field} id=user-merchant-portal-gui_merchant-account_last_name
+${mp_account_email_field} id=user-merchant-portal-gui_merchant-account_username
+${mp_account_change_password_button} xpath=//web-spy-button-action[@type='button'][contains(@action,'change-password')]//button
+${mp_account_current_password_field} id=security-merchant-portal-gui_change-password_current_password
+${mp_account_new_password_field} id=security-merchant-portal-gui_change-password_new_password_first
+${mp_account_repeat_new_password_field} id=security-merchant-portal-gui_change-password_new_password_second
+${mp_account_save_password_button} xpath=//web-spy-button[contains(@id,'change-password_save')]//button[@type='submit']
diff --git a/atest/testdata/performance/resources/pages/mp/mp_dashboard_page.robot b/atest/testdata/performance/resources/pages/mp/mp_dashboard_page.robot
new file mode 100644
index 0000000..12bd2b9
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_dashboard_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${mp_dashboard_main_content_locator} xpath=//web-mp-dashboard
+${mp_dashboard_manage_offers_button} xpath=//web-mp-dashboard//a[contains(@href,'product-offers')]
+${mp_dashboard_add_offer_button} xpath=//web-mp-dashboard//a[contains(@href,'product-list')]
+${mp_dashboard_manage_orders_button} xpath=//web-mp-dashboard//a[contains(@href,'orders')]
diff --git a/atest/testdata/performance/resources/pages/mp/mp_login_page.robot b/atest/testdata/performance/resources/pages/mp/mp_login_page.robot
new file mode 100644
index 0000000..a0d1c6b
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_login_page.robot
@@ -0,0 +1,6 @@
+*** Variables ***
+${mp_user_name_field} id=security-merchant-portal-gui_username
+${mp_password_field} id=security-merchant-portal-gui_password
+${mp_login_button} xpath=//button[@type='submit']
+${mp_login_failed_message} xpath=//spy-notification-view//div[contains(@class,'alert')]/span[contains(@class,'alert-message')]
+
diff --git a/atest/testdata/performance/resources/pages/mp/mp_offer_drawer.robot b/atest/testdata/performance/resources/pages/mp/mp_offer_drawer.robot
new file mode 100644
index 0000000..625ede4
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_offer_drawer.robot
@@ -0,0 +1,11 @@
+*** Variables ***
+${offer_active_checkbox} xpath=//web-spy-checkbox[@spy-id='productOffer_isActive']//span[@class='ant-checkbox-inner']
+${offer_merchant_sku} id=productOffer_merchantSku
+${stores_list_selector} xpath=//web-spy-select[@spy-id='productOffer_stores']//nz-select
+${offer_stock_input} xpath=//web-spy-input[@spy-id='productOffer_productOfferStocks_quantity']//input
+${offer_saved_popup} xpath=//spy-notification-view//span[contains(@class,'success')]
+${offer_always_in_stock_checkbox} xpath=//web-spy-checkbox[contains(@name,'Stock')]/label/span[contains(@class,'checkbox')]
+${offer_service_point_selector} xpath=//web-spy-select[@spy-id='productOffer_idServicePoint']//nz-select
+${offer_service_point_search_field} xpath=//web-spy-select[@spy-id='productOffer_idServicePoint']//nz-select//input
+${offer_services_selector} xpath=//web-spy-select[@spy-id='productOffer_services']//nz-select
+${offer_shipment_types_selector} xpath=//web-spy-select[@spy-id='productOffer_shipmentTypes']//nz-select
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/mp/mp_order_drawer.robot b/atest/testdata/performance/resources/pages/mp/mp_order_drawer.robot
new file mode 100644
index 0000000..3e07d65
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_order_drawer.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${order_grand_total} xpath=//web-spy-card[@spy-title='Totals']//div[text()='Grand Total']/following-sibling::div
+${order_state_label_on_drawer} xpath=//div[@class='mp-manage-order__states-col']//div[@class='mp-manage-order__states']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/mp/mp_product_drawer.robot b/atest/testdata/performance/resources/pages/mp/mp_product_drawer.robot
new file mode 100644
index 0000000..a898369
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_product_drawer.robot
@@ -0,0 +1,33 @@
+*** Variables ***
+${new_product_sku_field} id=create_product_abstract_form_sku
+${new_product_name_field} id=create_product_abstract_form_name
+${new_product_multiple_concretes_option} xpath=//span[contains(text(),'multiple concrete products')]/../span[@class='ant-radio']
+${new_product_super_attribute_first_row_name_selector} xpath=//div[@class='mp-product-attributes-selector__content']/div[1]/div[1]//spy-select
+${new_product_super_attribute_first_row_values_selector} xpath=//div[@class='mp-product-attributes-selector__content']/div[1]/div[2]//spy-select
+${new_product_super_attribute_second_row_name_selector} xpath=//div[@class='mp-product-attributes-selector__content']/div[2]/div[1]//spy-select
+${new_product_super_attribute_second_row_values_selector} xpath=//div[@class='mp-product-attributes-selector__content']/div[2]/div[2]//spy-select
+${new_product_add_super_attribute_button} xpath=//div[contains(@class,'mp-product-attributes-selector__button')]//span[contains(text(),'Add')]
+${new_product_created_popup} xpath=//spy-notification-view//span[contains(@class,'success')]
+${new_concrete_product_created_popup} xpath=//spy-notification-view//span[contains(@class,'success')]
+${new_product_concretes_preview_count} xpath=//mp-concrete-products-preview//spy-chips
+${new_product_submit_next_button} xpath=//button[@type='submit' and .//text()[normalize-space()='Next']]
+${new_product_submit_create_button} xpath=//button[@type='submit' and .//text()[normalize-space()='Create']]
+${product_concrete_submit_button} xpath=//div[@class='mp-edit-concrete-product__header']//button[@type='submit']
+${product_updated_popup} xpath=//spy-notification-view//span[contains(@class,'success')]
+${product_name_de_field} id=productAbstract_localizedAttributes_0_name
+${product_name_field} xpath=//input[contains(@name,'name')]/ancestor::web-spy-tabs[1]//div[contains(@class,'tabpane-active')]//input[not(ancestor::div[@aria-hidden='true'])]
+${product_store_selector} xpath=//web-spy-card[@spy-title='Stores']//web-spy-select
+${product_tax_selector} xpath=//web-spy-card[contains(@spy-title,'Tax Set')]//web-spy-select
+${product_drawer_concretes_tab} xpath=//div[contains(text(),'Concrete Products')]
+${product_concrete_active_checkbox} xpath=//span[contains(text(),'Concrete Product is active')]
+${product_concrete_stock_input} xpath=//web-spy-input[@spy-id='productConcreteEdit_productConcrete_stocks_quantity']//input
+${product_concrete_use_abstract_name_checkbox} xpath=//span[contains(text(),'Use Abstract Product name')]
+${product_concrete_searchability_selector} xpath=//web-spy-select[@spy-id='productConcreteEdit_searchability']
+${mp_add_price_button} xpath=//web-spy-card[@spy-title='Price']//button[.//text()[normalize-space()='Add']]
+${mp_add_concrete_price_button} xpath=//web-mp-edit-concrete-product//web-spy-card[@spy-title='Price']//button[.//text()[normalize-space()='Add']]
+${product_delete_price_row_button} xpath=//li[contains(@class,'ant-dropdown-menu-item')]
+${product_price_deleted_popup} xpath=//spy-notification-view//span[contains(@class,'success')]
+${mp_use_abstract_price_checkbox} xpath=//web-mp-content-toggle[@name='productConcreteEdit[useAbstractProductPrices]']//input[@type='checkbox'][contains(@class,'checkbox')]/parent::span
+${mp_add_concrete_products_button} xpath=//web-mp-edit-abstract-product-variants//web-spy-button-action[@type='button']//button
+${mp_product_name_field_de_tab} xpath=//input[contains(@name,'name')]/ancestor::web-spy-tabs[1]//button[@role='tab'][contains(.,'de_DE')]
+${mp_product_name_field_en_tab} xpath=//input[contains(@name,'name')]/ancestor::web-spy-tabs[1]//button[@role='tab'][contains(.,'en_US')]
diff --git a/atest/testdata/performance/resources/pages/mp/mp_products_page.robot b/atest/testdata/performance/resources/pages/mp/mp_products_page.robot
new file mode 100644
index 0000000..b241ad5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_products_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${add_product_button}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/mp/mp_profile_page.robot b/atest/testdata/performance/resources/pages/mp/mp_profile_page.robot
new file mode 100644
index 0000000..de1ce4b
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/mp/mp_profile_page.robot
@@ -0,0 +1,9 @@
+*** Variables ***
+${store_status_checkbox} xpath=//web-spy-checkbox[contains(@spy-id,'onlineProfileMerchant')][contains(@spy-id,'is_active')]
+${merchant_profile_name_field} id=merchantProfile_businessInfoMerchantProfile_name
+${merchant_profile_email_field} id=merchantProfile_onlineProfileMerchantProfile_public_email
+${merchant_profile_phone_field} id=merchantProfile_onlineProfileMerchantProfile_public_phone
+${merchant_profile_delivery_time_en_field} xpath=//web-spy-card[@spy-title='Average Delivery Time']//web-spy-collapsible[@spy-title='en_US']//input
+${merchant_profile_data_privacy_en_field} xpath=//web-spy-card[@spy-title='Data Privacy']//web-spy-collapsible[@spy-title='en_US']//textarea
+${merchant_profile_store_profile_url_en_field} id=merchantProfile_onlineProfileMerchantProfile_urlCollection_0_url
+${merchant_profile_store_profile_url_de_field} id=merchantProfile_onlineProfileMerchantProfile_urlCollection_1_url
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_address_page.robot b/atest/testdata/performance/resources/pages/yves/yves_address_page.robot
new file mode 100644
index 0000000..60fcc85
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_address_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{address_main_content_locator} ui_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Addresses')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Addresses')] ui_mp_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Addresses')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Addresses')] ui_suite=xpath=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Addresses')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_agent_assist_page.robot b/atest/testdata/performance/resources/pages/yves/yves_agent_assist_page.robot
new file mode 100644
index 0000000..1aa6450
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_agent_assist_page.robot
@@ -0,0 +1,6 @@
+*** Variables ***
+${agent_assist_overview_link} xpath=//div[@data-qa='component agent-control-item']//a[contains(@href,'agent/overview')]
+${agent_assist_menu_overview} xpath=//*[contains(@data-qa,'agent-navigation')]//*[contains(text(),'Overview')]
+${agent_assist_menu_quote_request} xpath=//li[@data-qa='component navigation-sidebar-item']//div[contains(text(),'Quote Requests')]
+${end_customer_assistance} xpath=//a[contains(@href,'switch_user')]
+${agent_logout} xpath=//a[contains(@href,'agent/logout')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_bazaarvoice_review_popup_form.robot b/atest/testdata/performance/resources/pages/yves/yves_bazaarvoice_review_popup_form.robot
new file mode 100644
index 0000000..f09e496
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_bazaarvoice_review_popup_form.robot
@@ -0,0 +1,12 @@
+*** Variables ****
+${bv_submit_button} xpath=//button[@name='bv-submit-button']
+${bv_review_title_input} id=bv-text-field-title
+${bv_review_text_area} id=bv-textarea-field-reviewtext
+${bv_recommend_product_true_label} id=bv-radio-isrecommended-true-label
+${bv_recommend_product_false_label} id=bv-radio-isrecommended-false-label
+${bv_nickname_input} id=bv-text-field-usernickname
+${bv_location_input} id=bv-text-field-userlocation
+${bv_email_input} id=bv-email-field-hostedauthentication_authenticationemail
+${bv_select_age_dropdown} id=bv-select-field-contextdatavalue_Age
+${bv_select_gender_dropdown} id=bv-select-field-contextdatavalue_Gender
+${bv_terms_and_conditions_checkbox} id=bv-checkbox-reviews-termsAndConditions
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_bundle_configurator_page.robot b/atest/testdata/performance/resources/pages/yves/yves_bundle_configurator_page.robot
new file mode 100644
index 0000000..523f3ba
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_bundle_configurator_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${bundle_configurator_main_content_locator} xpath=//*[@data-qa='component configurator-sidebar']
+${bundle_configurator_summary_step} xpath=//form[@name='configurator_state_form']//button[contains(.,'Summary')]
+${bundle_configurator_add_to_cart_button} xpath=//form[@name='configurator_state_form'][contains(@action,'add-to-cart')]/button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_catalog_page.robot b/atest/testdata/performance/resources/pages/yves/yves_catalog_page.robot
new file mode 100644
index 0000000..1a98763
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_catalog_page.robot
@@ -0,0 +1,9 @@
+*** Variables ***
+&{catalog_main_page_locator} ui_b2b=xpath=//main[contains(@class,'page-layout-main--catalog-page')] ui_b2c=xpath=//div[contains(@class,'catalog-right')] ui_suite=xpath=//form[contains(@class,'catalog__form')] ui_mp_b2b=xpath=//main[contains(@class,'page-layout-main--catalog-page')] ui_mp_b2c=xpath=//div[contains(@class,'catalog-right')]
+### ssp service products are not supported
+${catalog_product_card_locator} xpath=(//product-item[@data-qa='component product-item' and not(.//*[@src and contains(@src,'service')])][1]//a[contains(@class,'link-detail-page') and (contains(@class,'info') or contains(@class,'name'))])[1]
+&{catalog_products_counter_locator} ui_b2b=xpath=//*[contains(@class,'col--counter')] ui_b2c=xpath=//*[contains(@class,'sort__results col')] ui_mp_b2b=xpath=//*[contains(@class,'col--counter')] ui_mp_b2c=xpath=//*[contains(@class,'sort__results col')] ui_suite=xpath=//*[@data-qa='component sort']//strong
+${catalog_filter_apply_button} xpath=//section[@data-qa='component filter-section']//button[contains(@class,'button') and not(contains(@class,'category')) and not(ancestor::*[@data-qa='component asset-list'])]
+${catalog_add_to_cart_button} xpath=//button[contains(@title,'Add to Cart')]
+${catalog_sorting_selector} xpath=//select[@name='sort']
+${catalog_apply_sorting_button} xpath=//*[contains(@data-qa,"component sort")]//button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_address_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_address_page.robot
new file mode 100644
index 0000000..52d9816
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_address_page.robot
@@ -0,0 +1,45 @@
+*** Variables ***
+${checkout_address_billing_same_as_shipping_checkbox} xpath=//input[@id='addressesForm_billingSameAsShipping']/ancestor::toggler-checkbox
+&{checkout_address_delivery_dropdown} ui_b2b=xpath=//span[@id='select2-checkout-full-addresses-ct-container'] ui_b2c=xpath=//span[@id='select2-addressesForm_shippingAddress_id_customer_address-container'] ui_mp_b2b=xpath=//span[@id='select2-checkout-full-addresses-ct-container'] ui_mp_b2c=xpath=//span[@id='select2-addressesForm_shippingAddress_id_customer_address-container']
+&{checkout_address_delivery_selector} ui_b2c=xpath=//select[@id='addressesForm_shippingAddress_id_customer_address'] ui_b2b=xpath=//div[contains(@class,'shippingAddress')]//select[@name='checkout-full-addresses'][contains(@class,'address__form')] ui_suite=xpath=//div[contains(@class,'shippingAddress')]//select[contains(@name,'address')][contains(@class,'address__form')] ui_mp_b2b=xpath=//div[contains(@class,'shippingAddress')]//select[@name='checkout-full-addresses'][contains(@class,'address__form')] ui_mp_b2c=xpath=//select[@id='addressesForm_shippingAddress_id_customer_address'] ssp_b2b=xpath=(//address-item-form-field-list//select[@name='checkout-full-addresses' and not(ancestor::div[1][contains(@class, 'is-hidden')])])[1]
+${checkout_address_multiple_addresses_toggler_button} xpath=//multiple-shipment-toggler/button[contains(@class,'multiple-shipment-trigger')]
+${checkout_shipping_address_item_form} xpath=//div[@data-qa='component address-item-form']
+${checkout_new_billing_address_form} xpath=//div[contains(@class,'address__billing')][@data-qa='component form']
+${checkout_new_shipping_address_form} xpath=//div[contains(@class,'address__shipping')][@data-qa='component form']
+&{checkout_shipping_address_first_name_field} ui_b2b=id=addressesForm_shippingAddress_first_name ui_b2c=id=addressesForm_shippingAddress_first_name ui_suite=id=addressesForm_shippingAddress_first_name ui_mp_b2b=id=addressesForm_shippingAddress_first_name ui_mp_b2c=id=addressesForm_shippingAddress_first_name
+${checkout_shipping_address_last_name_field} id=addressesForm_shippingAddress_last_name
+${checkout_shipping_address_company_name_field} id=addressesForm_shippingAddress_company
+${checkout_shipping_address_street_field} id=addressesForm_shippingAddress_address1
+${checkout_shipping_address_house_number_field} id=addressesForm_shippingAddress_address2
+${checkout_shipping_address_additional_address_field} id=addressesForm_shippingAddress_address3
+${checkout_shipping_address_zip_code_field} id=addressesForm_shippingAddress_zip_code
+${checkout_shipping_address_city_field} id=addressesForm_shippingAddress_city
+${checkout_shipping_address_phone_field} id=addressesForm_shippingAddress_phone
+${checkout_shipping_address_salutation_selector} id=addressesForm_shippingAddress_salutation
+${checkout_shipping_address_country_selector} id=addressesForm_shippingAddress_iso2_code
+${ssp_checkout_shipping_address_first_name_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_first_name')]
+${ssp_checkout_shipping_address_last_name_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_last_name')]
+${ssp_checkout_shipping_address_company_name_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_company')]
+${ssp_checkout_shipping_address_street_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_address1')]
+${ssp_checkout_shipping_address_house_number_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_address2')]
+${ssp_checkout_shipping_address_additional_address_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_address3')]
+${ssp_checkout_shipping_address_zip_code_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_zip_code')]
+${ssp_checkout_shipping_address_city_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_city')]
+${ssp_checkout_shipping_address_phone_field} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@id,'shippingAddress_phone')]
+${ssp_checkout_shipping_address_salutation_selector} xpath=//*[contains(@data-qa,'address-item-form')]//*[contains(@name,'[shippingAddress][salutation]')]
+${ssp_checkout_shipping_address_country_selector} xpath=//*[contains(@data-qa,'address-item-form')]//select[contains(@id,'shippingAddress_iso2_code')]
+${checkout_address_submit_button} xpath=//button[@data-qa='submit-button']
+&{checkout_address_billing_selector} ui_b2c=xpath=//select[@id='addressesForm_billingAddress_id_customer_address'] ui_b2b=xpath=//select[contains(@class,'form-select-billingAddress')] ui_mp_b2b=xpath=//select[contains(@class,'form-select-billingAddress')] ui_mp_b2c=xpath=//select[@id='addressesForm_billingAddress_id_customer_address'] ui_suite=xpath=//select[contains(@class,'form-select-billingAddress')]
+${checkout_billing_address_salutation_selector} xpath=//select[@id='addressesForm_billingAddress_salutation']
+${checkout_billing_address_first_name_field} id=addressesForm_billingAddress_first_name
+${checkout_billing_address_last_name_field} id=addressesForm_billingAddress_last_name
+${checkout_billing_address_company_name_field} id=addressesForm_billingAddress_company
+${checkout_billing_address_street_field} id=addressesForm_billingAddress_address1
+${checkout_billing_address_house_number_field} id=addressesForm_billingAddress_address2
+${checkout_billing_address_additional_address_field} id=addressesForm_billingAddress_address3
+${checkout_billing_address_zip_code_field} id=addressesForm_billingAddress_zip_code
+${checkout_billing_address_city_field} id=addressesForm_billingAddress_city
+${checkout_billing_address_country_select} id=addressesForm_billingAddress_iso2_code
+${checkout_billing_address_phone_field} id=addressesForm_billingAddress_phone
+${manage_your_addresses_link} xpath=//a[contains(@href,'customer/address')]
+&{billing_address_section} ui_b2b=xpath=//form[@name='addressesForm']//div[contains(@class,'billing-same-as-shipping')] ui_b2c=xpath=//form[@name='addressesForm']//div[contains(@class,'billing-address')] ui_suite=xpath=//form[@name='addressesForm']//div[contains(@class,'billing-form')] ui_mp_b2b=xpath=//form[@name='addressesForm']//div[contains(@class,'billing-same-as-shipping')] ui_mp_b2c=xpath=//form[@name='addressesForm']//div[contains(@class,'billing-address')]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_cancel_payment_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_cancel_payment_page.robot
new file mode 100644
index 0000000..681a943
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_cancel_payment_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${cancel_payment_page_main_container_locator} xpath=//main//*[contains(text(),'Payment cancellation')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_login_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_login_page.robot
new file mode 100644
index 0000000..13a89f5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_login_page.robot
@@ -0,0 +1,14 @@
+*** Variables ***
+${yves_checkout_login_guest_firstName_field} id=guestForm_customer_first_name
+${yves_checkout_login_guest_lastName_field} id=guestForm_customer_last_name
+${yves_checkout_login_guest_email_field} id=guestForm_customer_email
+${yves_checkout_login_buy_as_guest_submit_button} xpath=//form[@name='guestForm']//button[contains(@data-qa,"submit-button")]
+${yves_checkout_signup_button} xpath=//toggler-radio[contains(@data-qa,'checkoutProceedAs register')]
+${yves_checkout_signup_first_name} id=registerForm_customer_first_name
+${yves_checkout_signup_last_name} id=registerForm_customer_last_name
+${yves_checkout_signup_email} id=registerForm_customer_email
+${yves_checkout_signup_password} id=registerForm_customer_password_pass
+${yves_checkout_signup_confirm_password} id=registerForm_customer_password_confirm
+${yves_checkout_signup_accept_terms} xpath=(//span[@class='checkbox__box'])[1]
+${yves_checkout_signup_tab} xpath=//form[contains(@name,'registerForm')]//button[contains(@type,'submit')]
+${yves_checkout_login_tab} xpath=//toggler-radio[contains(@data-qa,'checkoutProceedAs login')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_payment_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_payment_page.robot
new file mode 100644
index 0000000..a2f444d
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_payment_page.robot
@@ -0,0 +1,10 @@
+*** Variables ***
+${checkout_payment_invoice_date_of_birth_field} id=paymentForm_dummyPaymentInvoice_date_of_birth
+${checkout_payment_marketplace_invoice_date_field} id=paymentForm_dummyMarketplacePaymentInvoice_dateOfBirth
+${checkout_payment_invoice_locator} id=paymentForm_paymentSelection_dummyPaymentInvoice
+${checkout_payment_credit_card_locator} id=paymentForm_paymentSelection_dummyPaymentCreditCard
+${checkout_payment_card_number_field} id=paymentForm_dummyPaymentCreditCard_card_number
+${checkout_payment_name_on_card_field} id=paymentForm_dummyPaymentCreditCard_name_on_card
+${checkout_payment_card_expires_month_select} id=paymentForm_dummyPaymentCreditCard_card_expires_month
+${checkout_payment_card_expires_year_select} id=paymentForm_dummyPaymentCreditCard_card_expires_year
+${checkout_payment_card_security_code_field} id=paymentForm_dummyPaymentCreditCard_card_security_code
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_shipping_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_shipping_page.robot
new file mode 100644
index 0000000..e69de29
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_success_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_success_page.robot
new file mode 100644
index 0000000..8095c7a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_success_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{success_page_main_container_locator} ui_b2b=xpath=//main[contains(@class,'page-layout-main--success')]//div[contains(@class,'container--checkout-success')] ui_b2c=xpath=//div[contains(@class,'page-layout-checkout success-page')] ui_suite=xpath=//main//*[contains(text(),'Thank you')] ui_mp_b2b=xpath=//main[contains(@class,'page-layout-main--success')]//div[contains(@class,'container--checkout-success')] ui_mp_b2c=xpath=//div[contains(@class,'page-layout-checkout success-page')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_checkout_summary_page.robot b/atest/testdata/performance/resources/pages/yves/yves_checkout_summary_page.robot
new file mode 100644
index 0000000..46cf5d6
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_checkout_summary_page.robot
@@ -0,0 +1,13 @@
+*** Variables ***
+${checkout_summary_main_content_locator} xpath=//div[@data-qa='component summary-overview']
+${checkout_summary_submit_order_button} xpath=//form[@name='summaryForm']//button[contains(@class,'submit-button')]
+${checkout_summary_approver_dropdown} id=quote_approve_request_form_approverCompanyUserId
+${checkout_summary_send_request_button} xpath=//form[@name='quote_approve_request_form']//button[contains(@class,'button--success')]
+${checkout_summary_cancel_request_button} xpath=//div[@data-qa='component quote-approve-request']//form[contains(@action,'remove')]//button
+${checkout_summary_alert_warning} xpath=//*[@class="form form--checkout-form"]//ul[contains(@class,'alert')]
+${checkout_summary_quote_status} xpath=//div[contains(@data-qa,'component quote-status')]
+${checkout_summary_approve_request_button} xpath=//main[contains(@class,'page-layout-main--checkout-page')]//form[contains(@action,'approve')]//button
+${checkout_summary_decline_request_button} xpath=//main[contains(@class,'page-layout-main--checkout-page')]//form[contains(@action,'decline')]//button
+&{submit_checkout_form_button} ui_b2b=xpath=//div[contains(@class,'form--checkout-form')]//button[@data-qa='submit-button'] ui_b2c=xpath=//div[contains(@class,'form--checkout-form')]//button[@data-qa='submit-button'] ui_suite=xpath=//button[contains(@data-qa,'submit')] ui_mp_b2b=xpath=//div[contains(@class,'form--checkout-form')]//button[@data-qa='submit-button'] ui_mp_b2c=xpath=//div[contains(@class,'form--checkout-form')]//button[@data-qa='submit-button']
+&{checkout_summary_surcharge_amount} ui_b2c=xpath=//ul[@data-qa='component summary-overview']//li[contains(text(),'Surcharge')]//span ui_b2b=xpath=//div[@data-qa='component summary-overview']//li//div[contains(text(),'Surcharge')]/following-sibling::div ui_mp_b2b=xpath=//div[@data-qa='component summary-overview']//li//div[contains(text(),'Surcharge')]/following-sibling::div ui_mp_b2c=xpath=//ul[@data-qa='component summary-overview']//li[contains(text(),'Surcharge')]//span ui_suite=xpath=//*[contains(@data-qa,'sales-order-threshold-expense')]//div[contains(@class,'text')][last()]
+&{checkout_summary_alert_message} ui_b2c=xpath=//div[contains(@class,'checkout-actions')]//ul[contains(@class,'alert')]/li ui_b2b=xpath=//div[@data-qa='component form']//ul[contains(@class,'alert')]/li ui_mp_b2b=xpath=//div[@data-qa='component form']//ul[contains(@class,'alert')]/li ui_mp_b2c=xpath=//div[contains(@class,'checkout-actions')]//ul[contains(@class,'alert')]/li ui_suite=xpath=//div[@data-qa='component form']//ul[contains(@class,'alert')]/li
diff --git a/atest/testdata/performance/resources/pages/yves/yves_choose_bundle_to_configure_page.robot b/atest/testdata/performance/resources/pages/yves/yves_choose_bundle_to_configure_page.robot
new file mode 100644
index 0000000..6840adc
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_choose_bundle_to_configure_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${choose_bundle_main_content_locator} xpath=//div[@data-qa='component template-list']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_company_business_unit_page.robot b/atest/testdata/performance/resources/pages/yves/yves_company_business_unit_page.robot
new file mode 100644
index 0000000..7d386f5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_company_business_unit_page.robot
@@ -0,0 +1,6 @@
+*** Variables ***
+${create_company_business_unit_button} xpath=//a[contains(@href,'business-unit/create')]
+${create_company_business_unit_name_field} id=company_business_unit_form_name
+${create_company_business_unit_email_field} id=company_business_unit_form_email
+${create_company_business_unit_submit_button} xpath=//form[@name='company_business_unit_form']//button[@data-qa='submit-button']
+${company_business_unit_delete_button} xpath=(//a[contains(@href,'delete-confirmation')])[1]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_company_role_page.robot b/atest/testdata/performance/resources/pages/yves/yves_company_role_page.robot
new file mode 100644
index 0000000..86c338e
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_company_role_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${create_company_role_button} xpath=//a[contains(@href,'company-role/create')]
+${company_roles_table_locator} xpath=//*[contains(@data-qa,'role-table')]//table
+${create_company_role_name_field} id=company_role_form_name
+${create_company_role_submit_button} xpath=//form[@name='company_role_form']//button[@data-qa='submit-button']
diff --git a/atest/testdata/performance/resources/pages/yves/yves_company_user_page.robot b/atest/testdata/performance/resources/pages/yves/yves_company_user_page.robot
new file mode 100644
index 0000000..73833e4
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_company_user_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${create_company_user_button} xpath=//a[contains(@href,'company/user/create')]
+${create_company_user_business_unit_dropdown} xpath=//select[contains(@id,'company_business_unit')]
+${create_company_user_email_field} id=company_user_form_email
+${create_company_user_first_name_field} id=company_user_form_first_name
+${create_company_user_last_name_field} id=company_user_form_last_name
+${create_company_user_submit_button} xpath=//form[@name='company_user_form']//button[@data-qa='submit-button']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_company_users_page.robot b/atest/testdata/performance/resources/pages/yves/yves_company_users_page.robot
new file mode 100644
index 0000000..43dec9f
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_company_users_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${company_users_main_content_locator} xpath=//div[@data-qa='component user-table']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_create_return_page.robot b/atest/testdata/performance/resources/pages/yves/yves_create_return_page.robot
new file mode 100644
index 0000000..9efe3c7
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_create_return_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${create_return_main_content_locator} css=*[name=return_create_form]
+&{create_return_button} ui_b2b=xpath=//form[@name='return_create_form']//button[contains(@class,'return-create')] ui_b2c=xpath=//button[contains(@class,'return')] ui_suite=xpath=//div[@data-qa='component return-create-form']//button ui_mp_b2b=xpath=//form[@name='return_create_form']//button[contains(@class,'return-create')] ui_mp_b2c=xpath=//button[contains(@class,'return')]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_customer_account_page.robot b/atest/testdata/performance/resources/pages/yves/yves_customer_account_page.robot
new file mode 100644
index 0000000..66a70a1
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_customer_account_page.robot
@@ -0,0 +1,27 @@
+*** Variables ***
+${customer_account_business_unit_selector} id=company_user_account_selector_form_companyUserAccount
+${customer_account_address_form} css=*[name=addressForm]
+${customer_account_address_salutation_select} id=addressForm_salutation
+${customer_account_address_salutation_dropdown_field} id=select2-addressForm_salutation-container
+${customer_account_address_salutation_list} xpath=//li[@class='select2-results__option']
+${customer_account_address_first_name_field} id=addressForm_first_name
+${customer_account_address_last_name_field} id=addressForm_last_name
+${customer_account_address_company_name_field} id=addressForm_company
+${customer_account_address_street_field} id=addressForm_address1
+${customer_account_address_house_number_field} id=addressForm_address2
+${customer_account_address_additional_address_field} id=addressForm_address3
+${customer_account_address_zip_code_field} id=addressForm_zip_code
+${customer_account_address_city_field} id=addressForm_city
+${customer_account_address_country_drop_down_field} id=select2-addressForm_iso2_code-container
+${customer_account_address_phone_field} id=addressForm_phone
+${customer_account_address_is_default_shipping_checkbox} id=addressForm_is_default_shipping
+${customer_account_address_is_default_billing_checkbox} id=addressForm_is_default_billing
+${customer_account_address_submit_button} xpath=//main//button[@data-qa='submit-button']
+&{customer_account_add_new_address_button} ui_b2c=xpath=//a[@data-qa='customer-add-new-address'] ui_b2b=xpath=//a[contains(@href,'address/new')] ui_mp_b2b=xpath=//a[contains(@href,'address/new')] ui_mp_b2c=xpath=//a[@data-qa='customer-add-new-address'] ui_suite=xpath=//a[@data-qa='customer-add-new-address']
+&{customer_account_profile_salutation_span} ui_b2c=id=select2-profileForm_salutation-container ui_b2b=id=select2-profileForm_salutation-container ui_mp_b2c=id=select2-profileForm_salutation-container ui_mp_b2b=id=select2-profileForm_salutation-container ui_suite=xpath=//*[@id='profileForm_salutation']/option[@selected]
+${customer_account_profile_salutation_selector} id=profileForm_salutation
+${customer_account_profile_first_name_field} id=profileForm_first_name
+${customer_account_profile_last_name_field} id=profileForm_last_name
+${customer_account_profile_email_field} id=profileForm_email
+${customer_account_address_country} xpath=//select[contains(@id, 'addressForm_iso2_code')]
+${customer_account_profile_submit_profile_button} xpath=//form[@name='profileForm']//button[@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_customer_registration_page.robot b/atest/testdata/performance/resources/pages/yves/yves_customer_registration_page.robot
new file mode 100644
index 0000000..2beb6da
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_customer_registration_page.robot
@@ -0,0 +1,10 @@
+*** Variables ***
+${registration_page_title} xpath=//h2[contains(@class,'title') and contains(text(),'Sign Up')]
+${registration_first_name_field} id=registerForm_first_name
+${registration_last_name_field} id=registerForm_last_name
+${registration_email_field} id=registerForm_email
+${registration_password_field} id=registerForm_password_pass
+${registration_password_confirmation_field} id=registerForm_password_confirm
+${registration_accept_terms_checkbox} id=registerForm_accept_terms
+${registration_submit_button} xpath=//form[@name='registerForm']//button[@data-qa='submit-button']
+${registration_salutation_dropdown} id=select2-registerForm_salutation-container
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_cart_page.robot b/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_cart_page.robot
new file mode 100644
index 0000000..902adcd
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_cart_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${delete_shopping_cart_button} xpath=//form[@name='multi_cart_delete_form']/button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_list_page.robot b/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_list_page.robot
new file mode 100644
index 0000000..732fc39
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_delete_shopping_list_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${delete_shopping_list_button} xpath=//form[@name='shopping_list_delete_form']/button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_header_section.robot b/atest/testdata/performance/resources/pages/yves/yves_header_section.robot
new file mode 100755
index 0000000..86d66c8
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_header_section.robot
@@ -0,0 +1,31 @@
+*** Variables ***
+&{header_login_button} ui_b2b=xpath=//a[contains(@class,'button') and contains(@class,'header__login')] ui_b2c=xpath=//a[contains(@class,'button') and contains(@class,'header__login')] ui_suite=xpath=//header//*[@class='menu__item']//a[contains(@href,'/login')] ui_mp_b2b=xpath=//a[contains(@class,'button') and contains(@class,'header__login')] ui_mp_b2c=xpath=//a[contains(@class,'button') and contains(@class,'header__login')] api_suite=xpath=//header//*[@class='menu__item']//a[contains(@href,'/login')]
+${user_navigation_menu_login_button} xpath=//a[@class='user-block__button button col' and contains(text(),'Login')]
+&{user_navigation_icon_header_menu_item} ui_b2b=xpath=//header//a[contains(@href,'/customer/overview')] ui_b2c=xpath=//nav[@data-qa='component navigation-top']//*[@*='user-account'] ui_suite=xpath=//header//a[contains(@href,'/customer/overview')] ui_mp_b2b=xpath=//header//a[contains(@href,'/customer/overview')] ui_mp_b2c=xpath=//nav[@data-qa='component navigation-top']//*[@*='user-account'] api_suite=xpath=//header//a[contains(@href,'/customer/overview')]
+${user_header_logout_button} xpath=//header//a[contains(@href,'logout')]
+&{user_navigation_fly_out_header_menu_item} ui_b2b=xpath=//li[contains(@class,'user-navigation__item--user')]//nav[contains(@class,'user-navigation__sub-nav')]//ul[contains(@class,'list--secondary')] ui_b2c=xpath=//div[contains(@class,'user-block js-nav-overlay__drop-down-block')] ui_mp_b2b=xpath=//li[contains(@class,'user-navigation__item--user')]//nav[contains(@class,'user-navigation__sub-nav')]//ul[contains(@class,'list--secondary')] ui_mp_b2c=xpath=//div[contains(@class,'user-block js-nav-overlay__drop-down-block')]
+${company_name_icon_header_menu_item} xpath=//div[@class='header__top']//a[contains(@class,'navigation-top__company')]
+${store_switcher_header_menu_item} xpath=//*[@data-qa='component header']//select[contains(@name,'store')]
+${store_switcher_selected_option} xpath=//*[@data-qa='component header']//select[contains(@name,'store')]/option[@selected='']
+${company_account_navigation_fly_out_header_menu_item} xpath=//div[@class='header__top']//a[contains(@class,'navigation-top__company')]/..//nav[contains(@class,'navigation-list')]/ul
+${price_mode_switcher_header_menu_item} xpath=//*[@data-qa='component navigation-top']//select[@name='price-mode']
+&{currency_switcher_header_menu_item} ui_b2b=xpath=//*[@data-qa='component navigation-top']//select[@name='currency-iso-code'] ui_b2c=xpath=//div[@class='header__select']//select[@name='currency-iso-code'] ui_mp_b2b=xpath=//*[@data-qa='component navigation-top']//select[@name='currency-iso-code'] ui_mp_b2c=xpath=//div[@class='header__select']//select[@name='currency-iso-code'] ui_suite=xpath=//header//*[@data-qa='component navigation-top']//select[@name='currency-iso-code']
+${language_switcher_header_menu_item} xpath=//*[@class='header__top']//*[@data-qa='component language-switcher']//select
+${quick_order_icon_header_menu_item} xpath=//*[contains(@class,'icon--quick-order')]/ancestor::a
+&{shopping_list_icon_header_menu_item} ui_b2b=xpath=//header//li[contains(@class,'item')]/span[contains(@class,'item-inner')]/a[contains(@href,'shopping-list')]//*[contains(@data-qa,'icon')]/ancestor::a ui_mp_b2b=xpath=//header//li[contains(@class,'item')]/span[contains(@class,'item-inner')]/a[contains(@href,'shopping-list')]//*[contains(@data-qa,'icon')]/ancestor::a ui_suite=xpath=(//header//li[contains(@class,'item')]//a[contains(@href,'shopping-list')]/*[contains(@data-qa,'component icon')]/ancestor::a) ui_b2c=xpath=(//header//li[contains(@class,'item')]//a[contains(@href,'shopping-list')]/*[contains(@data-qa,'component icon')]/ancestor::a) ui_mp_b2c=xpath=(//header//li[contains(@class,'item')]//a[contains(@href,'shopping-list')]/*[contains(@data-qa,'component icon')]/ancestor::a)
+&{shopping_list_sub_navigation_widget} ui_mp_b2b=xpath=//header//li[contains(@class,'item')]/span[contains(@class,'item-inner')]//a[contains(@href,'shopping-list')]/ancestor::span/*[contains(@class,'list')] ui_b2b=xpath=//header//li[contains(@class,'item')]/span[contains(@class,'item-inner')]//a[contains(@href,'shopping-list')]/ancestor::span/*[contains(@class,'list')] ui_suite=//header//li[contains(@class,'item')]//a[contains(@href,'shopping-list')]/ancestor::li//ul[contains(@class,'list')]
+${shopping_list_sub_navigation_all_lists_button} //*[contains(@class,'icon--header-shopping-list')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-shopping-list')]//a[contains(.,'All Shopping Lists')]
+${shopping_list_sub_navigation_create_list_button} xpath=//*[contains(@class,'icon--header-shopping-list')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-shopping-list')]//a[contains(.,'Create New List')]
+&{shopping_car_icon_header_menu_item} ui_b2b=xpath=//*[contains(@class,'icon--cart')]/ancestor::a ui_b2c=xpath=//cart-counter[contains(@class,'navigation-top')] ui_suite=xpath=//header//cart-counter//a[contains(@href,'/cart')] ui_mp_b2b=xpath=//*[contains(@class,'icon--cart')]/ancestor::a ui_mp_b2c=xpath=//cart-counter[contains(@class,'navigation-top')] api_suite=xpath=//header//cart-counter//a[contains(@href,'/cart')] ui_suite=xpath=//header//cart-counter//a[contains(@href,'/cart')]
+${shopping_cart_sub_navigation_widget} xpath=//header//cart-counter//a[contains(@href,'/cart')]/ancestor::li//ul[contains(@class,'menu')][contains(@class,'wide')]
+${shopping_cart_sub_navigation_all_carts_button} //*[contains(@class,'icon--cart')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-cart')]//a[contains(.,'All Carts')]
+${shopping_cart_sub_navigation_create_cart_button} xpath=//*[contains(@class,'icon--cart')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-cart')]//a[contains(.,'Create New Cart')]
+${search_form_header_menu_item} xpath=//div[@data-qa='component search-form'][@data-search-id='desktop']//input[@name='q' and not(ancestor::asset-finder)]
+${search_form_open_menu_item} xpath=//div[(contains(@class,'header'))][(contains(@class,'search-open'))]
+${agent_customer_search_widget} xpath=//autocomplete-form[@data-qa='component autocomplete-form']//input[contains(@class,'autocomplete-form')][@type='text']
+${agent_confirm_login_button} xpath=//agent-control-bar[@data-qa='component agent-control-bar']//button[contains(@class,'button--success')]
+${agent_quote_requests_header_item} xpath=//agent-control-bar//a[contains(@href,'quote-request') and not(contains(@href,'detail'))]/ancestor::li[contains(@class,'item')][contains(@class,'-has-children') and not(contains(@class,'navigation'))]
+${agent_quote_requests_widget} xpath=//agent-control-bar//a[contains(@href,'quote-request') and not(contains(@href,'detail'))]/ancestor::li[contains(@class,'item')][contains(@class,'-has-children') and not(contains(@class,'navigation'))]//ul
+${wishlist_icon_header_navigation_widget} xpath=//nav[@data-qa='component navigation-top']//*[@*='#:wishlist']/ancestor::*[@data-qa='component icon'] | //nav[@data-qa='component navigation-top']//*[@*='wishlist']
+${cart_widget_item_quantity_counter} xpath=//*[@data-qa='component navigation-top']//span[contains(@class,'cart-counter__quantity js-cart-counter__quantity')]
+${header_logo_link} xpath=//*[@data-qa='component logo']//a
diff --git a/atest/testdata/performance/resources/pages/yves/yves_login_page.robot b/atest/testdata/performance/resources/pages/yves/yves_login_page.robot
new file mode 100755
index 0000000..fb8ad04
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_login_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${login_main_content_locator} xpath=(//div[contains(@data-qa,'component form')]//*[contains(text(),'Login')])[1]
+${email_field} id=loginForm_email
+${password_field} id=loginForm_password
+${form_login_button} xpath=//form[@name='loginForm']//*[contains(@class,'button')][@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_merchant_profile.robot b/atest/testdata/performance/resources/pages/yves/yves_merchant_profile.robot
new file mode 100644
index 0000000..4bda5cc
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_merchant_profile.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${merchant_profile_main_content_locator} xpath=//div[@data-qa='component merchant-profile']
+&{merchant_profile_name_header_locator} ui_mp_b2b=xpath=//div[@class='page-info']//h3 ui_mp_b2c=xpath=//h2[contains(@class,'spacing-top')] ui_suite=xpath=//*[contains(@data-qa,'breadcrumb')]//following-sibling::h3
+${merchant_profile_email_locator} xpath=//div[contains(@class,'merchant-profile')]//*[text()='Email Address']/../div
+${merchant_profile_phone_locator} xpath=//div[contains(@class,'merchant-profile')]//*[text()='Phone']/../div
+${merchant_profile_delivery_time_locator} xpath=//div[contains(@class,'merchant-profile')]//*[text()='Delivery Time']/../div
+${merchant_profile_data_privacy_locator} xpath=//div[contains(@class,'merchant-profile')]//*[text()='Data Privacy']/following-sibling::*
diff --git a/atest/testdata/performance/resources/pages/yves/yves_newsletter_page.robot b/atest/testdata/performance/resources/pages/yves/yves_newsletter_page.robot
new file mode 100644
index 0000000..6dcfc57
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_newsletter_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{newsletter_main_content_locator} ui_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Newsletter')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Newsletter')] ui_mp_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Newsletter')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Newsletter')] ui_suite=xpath=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Newsletter')]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_order_details_page.robot b/atest/testdata/performance/resources/pages/yves/yves_order_details_page.robot
new file mode 100644
index 0000000..6d4806a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_order_details_page.robot
@@ -0,0 +1,15 @@
+*** Variables ***
+${order_details_main_content_locator} xpath=//main//form[contains(@name,'Reorder')][contains(@action,'reorder')]//*[contains(@data-qa,'reorder-form')] | //customer-reorder-form[@data-qa='component customer-reorder-form']
+&{order_details_reorder_all_button} ui_b2b=xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//button[contains(.,'Reorder all')] | //*[@data-qa="reorder-all-button"] ui_b2c=xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//button[contains(.,'Reorder all')] | //*[@data-qa="reorder-all-button"] ui_mp_b2b=xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//button[contains(.,'Reorder all')] | //*[@data-qa="reorder-all-button"] ui_mp_b2c=xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//button[contains(.,'Reorder all')] | //*[@data-qa="reorder-all-button"] ui_suite=xpath=//form[contains(@action,'reorder')][input[contains(@id,'cartReorderForm')]]//button[@class="button"] | //form[@name='customerReorderWidgetForm']//button
+${order_details_reorder_selected_items_button} xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//button[contains(.,'Reorder selected items')]
+&{order_details_shipping_address_locator} ui_b2b=xpath=//div[@class='summary-sidebar__item']//ul[@data-qa='component display-address'] ui_mp_b2b=xpath=//div[@class='summary-sidebar__item']//ul[@data-qa='component display-address'] ui_mp_b2c=xpath=//*[@data-qa="component order-detail-table"]//div[@class='summary-sidebar__item'][1]/div[contains(@class,'text')] ui_b2c=xpath=//*[@data-qa="component order-detail-table"]//div[@class='summary-sidebar__item'][1]/div[contains(@class,'text')] ui_suite=xpath=//div[@class='order-detail-table']//ul[@data-qa='component display-address']
+${order_details_cancel_button_locator} xpath=(//remote-form-submit[contains(@form-action,'cancel')]//button | //*[contains(@name,'orderCancelForm')]//button)[1]
+${order_details_write_comment_placeholder} xpath=//div[@data-qa='component add-comment-form']//form[@method='POST']/textarea
+${order_details_edit_comment_placeholder} xpath=//comment-form[@data-qa='component comment-form']//form[@method='POST']//textarea
+${order_details_add_comment_button} xpath=//button[contains(@class,"js-add-comment-form__button")]
+${order_details_edit_comment_button} xpath=//button[contains(@class,"button--hollow-icon-small") and not (contains(@class,"js-comment-form__remove-button"))]
+${order_details_update_comment_button} xpath=//button[contains(@action,"/comment/update")]
+${order_details_remove_comment_button} xpath=//button[contains(@action,"/comment/remove")]
+${yves_order_details_page_comments} xpath=//comment-thread-list//comment-form//textarea
+${add_comment_button_order_details_page} xpath=//button[contains(@action,'comment/add')] | //button[contains(@class,'add-comment')]
+${order_details_page_add_comments_textbox} xpath=//textarea[ancestor::form[@method='POST'] and not(ancestor::comment-thread-list)]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_order_history_page.robot b/atest/testdata/performance/resources/pages/yves/yves_order_history_page.robot
new file mode 100644
index 0000000..f55ea0a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_order_history_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${order_history_main_content_locator} xpath=//div[contains(@data-qa,'component order-table')]
+${order_history_search_filter_button} xpath=//button[contains(@class,'order-filter-button')]
+${order_history_apply_filter_button} xpath=//div[@data-qa='component order-filters']//button[@name='buttonSubmit']
+${order_history_search_filter_business_unit_dropdown} xpath=//span[@id='select2-orderSearchForm_filters_companyBusinessUnit-container']
diff --git a/atest/testdata/performance/resources/pages/yves/yves_overview_page.robot b/atest/testdata/performance/resources/pages/yves/yves_overview_page.robot
new file mode 100644
index 0000000..e953cae
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_overview_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{overview_main_content_locator} ui_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Overview')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Overview')] ui_mp_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Overview')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Overview')] ui_suite=xpath=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Overview')]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_product_configurator_page.robot b/atest/testdata/performance/resources/pages/yves/yves_product_configurator_page.robot
new file mode 100644
index 0000000..c2fb03a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_product_configurator_page.robot
@@ -0,0 +1,9 @@
+*** Variables ***
+${configurator_back_button} xpath=//a[contains(@class,'header__back')]
+${configurator_save_button} xpath=//button[@type='submit' or contains(text(),' Save configurations')]
+${configurator_store} xpath=//div[@class='header__bottom']//li[contains(.,'Store')]/span
+${configurator_locale} xpath=//div[@class='header__bottom']//li[contains(.,'Locale')]/span
+${configurator_price_mode} xpath=//div[@class='header__bottom']//li[contains(.,'Price')]/span
+${configurator_currency} xpath=//div[@class='header__bottom']//li[contains(.,'Currency')]/span
+${configurator_sku} xpath=//app-product-details//div[contains(@class,'details')]/span[@data-qa='product-details-sku']
+${unsaved_product_configurations_leave_button} xpath=//app-header//div[@data-qa='header-guard-modal']//div/button[@data-qa='header-guard-leave-button']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_product_details_page.robot b/atest/testdata/performance/resources/pages/yves/yves_product_details_page.robot
new file mode 100644
index 0000000..964f8eb
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_product_details_page.robot
@@ -0,0 +1,49 @@
+*** Variables ***
+&{pdp_main_container_locator} ui_b2b=xpath=//main[contains(@class,'page-layout-main--pdp')] ui_b2c=xpath=//*[@itemtype='https://schema.org/Product']//main[contains(@class,'page-layout')] ui_suite=xpath=//section[@itemtype="https://schema.org/Product"] ui_mp_b2b=xpath=//main[contains(@class,'page-layout-main--pdp')] ui_mp_b2c=xpath=//*[@itemtype='https://schema.org/Product']//main[contains(@class,'page-layout')]
+${pdp_price_element_locator} xpath=//volume-price[@class='custom-element volume-price']//span[contains(@class,'volume-price__price')][not(ancestor::form[contains(@action,'cart/add')])]
+${pdp_original_price_element_locator} xpath=//volume-price[@class='custom-element volume-price']//span[contains(@class,'volume-price')][contains(@class,'original')][not(ancestor::form[contains(@action,'cart/add')])]
+${pdp_add_to_cart_button} xpath=//button[contains(@class,'button') and @data-qa='add-to-cart-button']
+&{pdp_add_to_cart_disabled_button} ui_b2c=xpath=//button[@disabled and contains(text(),'Add to Cart')] ui_b2b=xpath=//button[@disabled and contains(@data-qa,'add-to-cart-button')] ui_mp_b2b=xpath=//button[@disabled and contains(@data-qa,'add-to-cart-button')] ui_mp_b2c=xpath=//button[@disabled and contains(text(),'Add to Cart')] ui_mp_b2c=xpath=//button[@disabled and contains(text(),'Add to Cart')] ui_suite=xpath=//button[contains(@class,'add-to-cart')][@disabled]
+${pdp_add_to_wishlist_button} xpath=//button[@type='submit'][contains(.,'Wishlist')]
+&{pdp_quantity_input_filed} ui_b2b=xpath=//div[@class='product-configurator__add-to-cart']//input[contains(@class,'number-input')][contains(@class,'quantity-counter')] ui_b2c=//*[@data-qa='quantity-input'] ui_mp_b2b=xpath=//div[@class='product-configurator__add-to-cart']//input[contains(@class,'number-input')][contains(@class,'quantity-counter')] ui_mp_b2c=//*[@data-qa='quantity-input'] ui_suite=xpath=//form[contains(@action,'cart/add')]//select[@name='quantity']
+&{pdp_alternative_products_slider} ui_b2b=xpath=//*[@data-qa='component product-alternative-slider'] ui_b2c=xpath=//*[contains(@class,'product-slider')][contains(.,'Alternative products')]/../slick-carousel ui_mp_b2b=xpath=//*[@data-qa='component product-alternative-slider'] ui_mp_b2c=xpath=//*[contains(@class,'product-slider')][contains(.,'Alternative products')]/../slick-carousel ui_suite=xpath=(//*[contains(text(),'Alternative products')]/following-sibling::simple-carousel)[1]
+${pdp_measurement_sales_unit_selector} css=*[name=id-product-measurement-sales-unit]
+${pdp_measurement_unit_notification} xpath=//packaging-unit-quantity-selector/div[contains(@class,'measurement-unit-choice')]
+&{pdp_increase_quantity_button} ui_b2b=xpath=//div[@class='product-configurator__add-to-cart']//button[contains(@class,'quantity-counter__button--increment')] ui_mp_b2b=xpath=//div[@class='product-configurator__add-to-cart']//button[contains(@class,'quantity-counter__button--increment')] ui_b2c=xpath=//quantity-counter[@data-qa='component quantity-counter']//*[contains(@class,'quantity-counter__incr')] ui_mp_b2c=xpath=//quantity-counter[@data-qa='component quantity-counter']//*[contains(@class,'quantity-counter__incr')]
+&{pdp_decrease_quantity_button} ui_b2b=xpath=//div[@class='product-configurator__add-to-cart']//button[contains(@class,'quantity-counter__button--decrement')] ui_mp_b2b=xpath=//div[@class='product-configurator__add-to-cart']//button[contains(@class,'quantity-counter__button--decrement')] ui_b2c=xpath=//quantity-counter[@data-qa='component quantity-counter']//*[contains(@class,'quantity-counter__decr')] ui_mp_b2c=xpath=//quantity-counter[@data-qa='component quantity-counter']//*[contains(@class,'quantity-counter__decr')]
+${pdp_variant_selector} xpath=//*[@data-qa='component variant']//select
+${pdp_variant_custom_selector} xpath=//section[@data-qa='component variant-configurator']//span[contains(@id,'select2-attribute')]
+${pdp_variant_custom_selector_results} xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]
+${pdp_amount_input_filed} xpath=//formatted-number-input/input[contains(@class,'user-amount')]
+${pdp_packaging_unit_notification} xpath=//div[contains(@class,'packaging-unit-quantity-selector')][contains(@class,'packaging-unit-choice')]/div[contains(@class,'packaging-unit')]//button
+&{pdp_product_bundle_include_small} ui_b2b=xpath=//div[contains(@data-qa,'component bundle-items')] ui_b2c=xpath=//div[contains(@data-qa,'component bundle-items')] ui_mp_b2b=xpath=//div[contains(@data-qa,'component bundle-items')] ui_mp_b2c=xpath=//div[contains(@data-qa,'component bundle-items')] ui_suite=xpath=//div[contains(@data-qa,'component bundle-items')]
+${pdp_product_bundle_include_large} xpath=//div[@data-qa='component product-bundle']
+&{pdp_related_products} ui_b2b=xpath=//*[contains(@class,'title--product-slider')][contains(.,'Similar products')]/../slick-carousel ui_b2c=xpath=//*[contains(@class,'product-slider')][contains(.,'You might also like')]/../slick-carousel ui_mp_b2b=xpath=//*[contains(@class,'title--product-slider')][contains(.,'Similar products')]/../slick-carousel ui_mp_b2c=xpath=//*[contains(@class,'product-slider')][contains(.,'You might also like')]/../slick-carousel ui_suite=xpath=(//main//simple-carousel[@data-qa='component simple-carousel'])[1]
+${pdp_add_to_shopping_list_button} xpath=//button[@data-qa='add-to-shopping-list-button']
+&{pdp_product_sku} ui_b2b=xpath=//section[@class='product-configurator']//div[@class='product-configurator__sku'] ui_b2c=//section[@class='product-detail']//div[@class='spacing-top spacing-top--bigger'] ui_mp_b2b=xpath=//section[@class='product-configurator']//div[@class='product-configurator__sku'] ui_mp_b2c=//section[@class='product-detail']//div[@class='spacing-top spacing-top--bigger'] ui_suite=xpath=//*[contains(@data-qa,'product-configurator')]//*[@itemprop='sku']
+${pdp_shopping_list_selector} xpath=//form[contains(@action,'shopping-list')]//select[@name='idShoppingList']
+&{pdp_sales_label} ui_b2b=xpath=//*[@class='page-info']//*[@data-qa='component label-group']//span[contains(text(),'SALE')] ui_b2c=xpath=//*[contains(@data-qa,'product-carousel')]//*[@data-qa='component label-group']//span[contains(text(),'SALE')] ui_mp_b2b=xpath=//*[@id='main-content']//*[@data-qa='component label-group']//span[contains(text(),'SALE')] ui_mp_b2c=xpath=//*[contains(@data-qa,'product-carousel')]//*[@data-qa='component label-group']//span[contains(text(),'SALE')] ui_suite=xpath=(//*[contains(@data-qa,'product-carousel')]//*[contains(@data-qa,'label')]//span[contains(.,'SALE')])[1]
+&{pdp_new_label} ui_b2b=xpath=//*[@class='page-info']//*[@data-qa='component label-group']//span[contains(text(),'New')] ui_b2c=xpath=//*[contains(@data-qa,'product-carousel')]//*[@data-qa='component label-group']//span[contains(text(),'New')] ui_mp_b2b=xpath=//*[@id='main-content']//*[@data-qa='component label-group']//span[contains(text(),'New')] ui_mp_b2c=xpath=//*[contains(@data-qa,'product-carousel')]//*[@data-qa='component label-group']//span[contains(text(),'New')] ui_suite=xpath=(//*[contains(@data-qa,'product-carousel')]//*[contains(@data-qa,'label')]//span[contains(.,'New')])[1]
+${pdp_warranty_option} xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Warranty')]
+${pdp_insurance_option} xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Insurance')]
+&{pdp_limited_warranty_option} ui_b2b=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'limited warranty')] ui_b2c=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'limited warranty')] ui_mp_b2b=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'limited warranty')] ui_mp_b2c=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'limited warranty')] ui_suite=xpath=//*[contains(@data-qa,'product-option')][contains(@data-qa,'warranty')]
+${pdp_insurance_coverage_option} xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'insurance coverage')]
+&{pdp_gift_wrapping_option} ui_b2b=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Gift wrapping')] ui_b2c=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Gift wrapping')] ui_mp_b2b=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Gift wrapping')] ui_mp_b2c=xpath=//*[contains(@class,'option')]//*[contains(@class,'title')][contains(text(),'Gift wrapping')] ui_suite=xpath=//*[contains(@data-qa,'product-option')][contains(@data-qa,'gift')]
+${pdp_product_reviews_list} xpath=//*[contains(text(),'Product Reviews')]/following-sibling::div/article[@class='review']
+${pdp_product_not_available_text} xpath=//form[@class='js-product-configurator__form-add-to-cart']//*[contains(@class,'text')][contains(text(),'This product is currently not available.')]
+${pdp_availability_notification_email_field} xpath=//input[@id='availabilityNotificationSubscriptionForm_email']
+${pdp_wishlist_dropdown} xpath=//select[contains(@name,'wishlist-name')]
+${pdp_reset_selected_variant_locator} xpath=(//div[@class='variant']//button | //div[@class='variant']//a)[1]
+${pdp_back_in_stock_subscribe_button} xpath=//form[@id='availability_notification_subscription']//button[@data-qa='submit-button']
+${pdp_back_in_stock_unsubscribe_button} xpath=//form[@id='availability_unsubscribe']//button[@type='submit']
+${pdp_bazaarvoice_write_review_button} xpath=//button[contains(@class,'bv-write-review')]
+${pdp_bazaarvoice_questions_locator} xpath=//div[@data-bv-show='questions']
+${pdp_bazaarvoice_intine_rating_locator} xpath=//section[@data-bv-show='inline_rating']
+${referrer_url} xpath=//header//form[contains(@action,'currency/switch')]//input[@name='referrer-url']
+${pdp_product_name} xpath=//h1[contains(@class,'title')]
+${pdp_configure_button} xpath=(//*[contains(@action,'product-configurator-gateway') or contains(@form-action,'product-configurator-gateway')]//button)[1]
+${pdp_configuration_status} xpath=(//span[@data-qa='component status'])[1]
+&{pdp_configuration_option_one} ui_b2b=xpath=(//*[contains(@data-qa,'collapsible-list')]//div[contains(@class,'item')][1]/*[contains(@class,'value')])[1] ui_mp_b2b=xpath=(//*[contains(@data-qa,'collapsible-list')]//div[contains(@class,'item')][1]/*[contains(@class,'value')])[1] ui_b2c=xpath=(//*[contains(@data-qa,'collapsible-list')]//*[contains(@class,'value')])[1] ui_mp_b2c=xpath=(//*[contains(@data-qa,'collapsible-list')]//*[contains(@class,'value')])[1] ui_suite=xpath=((//*[contains(@data-qa,'collapsible-list')])[1]//div)[2]
+&{pdp_configuration_option_two} ui_b2b=xpath=(//*[contains(@data-qa,'collapsible-list')]//div[contains(@class,'item')][2]/*[contains(@class,'value')])[1] ui_mp_b2b=xpath=(//*[contains(@data-qa,'collapsible-list')]//div[contains(@class,'item')][2]/*[contains(@class,'value')])[1] ui_b2c=xpath=(//*[contains(@data-qa,'collapsible-list')]//*[contains(@class,'value')])[2] ui_mp_b2c=xpath=(//*[contains(@data-qa,'collapsible-list')]//*[contains(@class,'value')])[2] ui_suite=xpath=((//*[contains(@data-qa,'collapsible-list')])[1]//div)[last()]
+${configurator_configuration_status} xpath=//app-product-details//div[contains(@class,'details')]/div[@data-qa='product-details-unavailability-notification' or @data-qa='product-details-availability-notification']
+${configurator_price_element_locator} xpath=//app-product-details//div[contains(@class,'details')]/div/span[@data-qa='product-details-price']
diff --git a/atest/testdata/performance/resources/pages/yves/yves_product_sets_page.robot b/atest/testdata/performance/resources/pages/yves/yves_product_sets_page.robot
new file mode 100644
index 0000000..7084055
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_product_sets_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${product_set_main_content_locator} xpath=//product-set-details[@data-qa='component product-set-details']
+${add_all_product_to_the_shopping_cart} xpath=//form[@name='addItemsForm']//button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_profile_page.robot b/atest/testdata/performance/resources/pages/yves/yves_profile_page.robot
new file mode 100644
index 0000000..69a9954
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_profile_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{profile_main_content_locator} ui_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Profile')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Profile')] ui_mp_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Profile')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Profile')] ui_suite=xpath=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Profile')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_quick_order_page.robot b/atest/testdata/performance/resources/pages/yves/yves_quick_order_page.robot
new file mode 100644
index 0000000..33d0b09
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_quick_order_page.robot
@@ -0,0 +1,12 @@
+*** Variables ***
+${quick_order_main_content_locator} css=*[name=quick_order_form]
+${quick_order_add_articles_text_area} id=text_order_form_textOrder
+${quick_order_verify_button} css=*[name=textOrder]
+${quick_order_add_to_cart_button} css=*[name=addToCart]
+${quick_order_create_order_button} css=*[name=createOrder]
+${quick_order_add_to_shopping_list_button} css=*[name=addToShoppingList]
+${quick_order_shopping_list_selector} css=*[name=idShoppingList]
+${quick_order_first_empty_row} xpath=(//div[contains(@data-qa,'component quick-order-rows')]//input[contains(@class,'autocomplete')][@value=''])[1]
+${quick_order_add_more_rows} xpath=//a[contains(@href,'#add-more')] | //form[@name="quick_order_form"]//button[contains(@class,'add-row')]
+${quick_order_row_search_results} xpath=(//div[contains(@data-qa,'component quick-order-rows')]//*[contains(@class,'autocomplete')][@value=''])[1]/ancestor::quick-order-row//ul[@data-qa='component products-list']
+${quick_order_row_merchant_selector} xpath=(//select[contains(@id,'quick_order_form[items]')][contains(@id,'product_offer_reference')])[last()]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_quote_request_page.robot b/atest/testdata/performance/resources/pages/yves/yves_quote_request_page.robot
new file mode 100644
index 0000000..3a4a653
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_quote_request_page.robot
@@ -0,0 +1,15 @@
+*** Variables ***
+${quote_request_main_content_locator} xpath=//*[contains(@data-qa,'quote-request-information')]
+${quote_request_sidebar_locator} xpath=//aside[@data-qa='component quote-request-sidebar']
+${quote_request_back_to_list_button} xpath=//aside[@data-qa='component quote-request-sidebar']//a[contains(.,'Back')]
+${quote_request_cancel_button} xpath=//aside[@data-qa='component quote-request-sidebar']//a[contains(@href,'cancel')]
+${quote_request_revise_button} xpath=//a[contains(@href,'revise')]
+${quote_request_convert_to_cart_button} xpath=//a[contains(@href,'convert-to-cart')]
+${quote_request_save_button} css=*[name=save]
+${quote_request_send_to_customer_button} css=*[name=sendToCustomer]
+${quote_request_edit_button} xpath=//aside[@data-qa='component quote-request-sidebar']//a[contains(@href,'edit')]
+${quote_request_edit_items_button} xpath=//a[contains(@href,'edit-items')]
+${quote_request_save_and_back_to_edit_button} css=*[name=saveAndBack]
+${quote_request_notes_text_area} id=quote_request_form_latestVersion_metadata_note
+${quote_request_send_to_agent_button} xpath=//button[@name="sendToUser"] | //a[contains(@href,'send-to-user')]
+${quote_request_convert_from_cart_confirm_button} xpath=//button[contains(@class,'button')][contains(text(),'Submit')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_quote_requests_page.robot b/atest/testdata/performance/resources/pages/yves/yves_quote_requests_page.robot
new file mode 100644
index 0000000..93720c3
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_quote_requests_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${quote_requests_main_content_locator} xpath=//div[@data-qa='component quote-request-table']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_return_details_page.robot b/atest/testdata/performance/resources/pages/yves/yves_return_details_page.robot
new file mode 100644
index 0000000..89167e2
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_return_details_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${return_details_main_content_locator} xpath=//div[@data-qa='component return-overview']
+${return_details_print_slip_button} xpath=//a[contains(@href,'slip-print')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_return_slip_page.robot b/atest/testdata/performance/resources/pages/yves/yves_return_slip_page.robot
new file mode 100644
index 0000000..0fe0412
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_return_slip_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${return_slip_products_table} xpath=//table[contains(@class,'return-slip-items')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_returns_page.robot b/atest/testdata/performance/resources/pages/yves/yves_returns_page.robot
new file mode 100644
index 0000000..1244a90
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_returns_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+&{returns_main_content_locator} ui_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Returns')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Returns')] ui_mp_b2b=xpath=//section[contains(@data-qa,'component section')]//h3[contains(text(),'Returns')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Returns')] ui_suite=xpath=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Returns')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_set_new_password_page.robot b/atest/testdata/performance/resources/pages/yves/yves_set_new_password_page.robot
new file mode 100755
index 0000000..673df42
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_set_new_password_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${new_password_field} id=restoreForm_password_pass
+${confirm_new_password_field} id=restoreForm_password_confirm
+${new_password_submit_button} xpath=//form[@name='restoreForm']//*[contains(@class,'button')][@type='submit']
diff --git a/atest/testdata/performance/resources/pages/yves/yves_shopping_cart_page.robot b/atest/testdata/performance/resources/pages/yves/yves_shopping_cart_page.robot
new file mode 100644
index 0000000..c0ab2d5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_shopping_cart_page.robot
@@ -0,0 +1,25 @@
+*** Variables ***
+&{shopping_cart_main_content_locator} ui_b2b=xpath=//*[@data-qa='component cart-sidebar'] ui_b2c=xpath=//*[@class='page-layout-cart'] ui_mp_b2b=xpath=//*[@data-qa='component cart-sidebar'] ui_mp_b2c=xpath=//*[@class='page-layout-cart'] ui_suite=xpath=//form[@name='cartCodeForm']
+${shopping_cart_checkout_button} xpath=//main//a[@data-qa='cart-go-to-checkout']
+${shopping_cart_request_quote_button} xpath=//a[contains(@href,'/quote-request/create')]
+&{shopping_cart_upp-sell_products_section} ui_b2b=xpath=//main[contains(@class,'cart')]//slick-carousel[@data-qa='component slick-carousel'] ui_b2c=xpath=//div[contains(@data-qa,'component extra-product')] ui_mp_b2b=xpath=//main[contains(@class,'cart')]//slick-carousel[@data-qa='component slick-carousel'] ui_mp_b2c=xpath=//main[contains(@class,'cart')]//slick-carousel[@data-qa='component slick-carousel'] ui_suite=(//div[contains(@class,'upselling')]//simple-carousel)[1]
+${shopping_cart_locked_cart_form} xpath=//form[@class='cart-locking__form']
+&{shopping_cart_cart_title} ui_mp_b2b=xpath=//*[contains(@class,'cart-title__text')] ui_b2b=xpath=//*[contains(@class,'cart-title__text')] ui_suite=xpath=//*[contains(@class, 'box')]/h3
+${request_a_quote_button} xpath=//a[contains(@class,'button')][contains(text(),'Request a Quote')]
+${shopping_cart_voucher_code_section_toggler} xpath=//input[@id='cartCodeForm_code']//ancestor::div[@data-qa='component toggler-item']
+${shopping_cart_voucher_code_field} id=cartCodeForm_code
+${shopping_cart_voucher_code_redeem_button} xpath=//button[contains(.,'Redeem') and contains(@data-qa,'submit')]
+${shopping_cart_promotional_product_section} xpath=(//product-item[contains(@data-qa,'component product-item')])[1]
+${shopping_cart_promotional_product_add_to_cart_button} xpath=(//product-item[contains(@data-qa,'component product-item')]//form[contains(@name,'addToCartForm')]//button[@data-init-single-click])[1]
+&{shopping_cart_promotional_product_increase_quantity_button} ui_b2c=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter//div[contains(@class,'incr')])[1] ui_b2b=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter/button[contains(@class,'increment')])[1] ui_mp_b2b=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter/button[contains(@class,'increment')])[1] ui_mp_b2c=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter//div[contains(@class,'incr')])[1] ui_suite=
+&{shopping_cart_promotional_product_decrease_quantity_button} ui_b2c=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter//div[contains(@class,'button button--quantity js-quantity-counter__decr')])[1] ui_b2b=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter/button[contains(@class,'decrement')])[1] ui_mp_b2b=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter/button[contains(@class,'decrement')])[1] ui_mp_b2c=xpath=(//product-item[contains(@data-qa,'component product-item')]//quantity-counter//div[contains(@class,'js-quantity-counter__decr')])[1]
+&{shopping_cart_surcharge_amount} ui_b2c=xpath=//div[@data-qa='component cart-summary']//li[contains(text(),'Surcharge')]//span ui_b2b=xpath=//div[@data-qa='component cart-summary']//li//div[contains(text(),'Surcharge')]/following-sibling::div ui_mp_b2b=xpath=//div[@data-qa='component cart-summary']//li//div[contains(text(),'Surcharge')]/following-sibling::div ui_mp_b2c=xpath=//div[@data-qa='component cart-summary']//li[contains(text(),'Surcharge')]//span ui_suite=xpath=//div[@data-qa='component cart-summary']//li//div[contains(text(),'Surcharge')]/following-sibling::div
+${shopping_cart_write_comment_placeholder} xpath=//*[contains(@data-qa,'comment-form')]//form[@method='POST']/textarea
+${shopping_cart_add_comment_button} xpath=//*[contains(@data-qa,'comment-form')]//form[@method='POST']//button
+${shopping_cart_edit_comment_button} xpath=(//comment-form//*[@title='edit']/ancestor::button)[1]
+${shopping_cart_edit_comment_placeholder} xpath=(//comment-form[@data-qa='component comment-form']//form[@method='POST']//textarea)[1]
+${shopping_cart_update_comment_button} xpath=(//comment-form//button[contains(@formaction,"/comment/async/update")])[1] | (//comment-form//button[contains(@action,"/comment/update")])[1]
+${shopping_cart_remove_comment_button} xpath=(//comment-form//button[contains(@formaction,"remove")])[1] | (//comment-form//button[contains(@action,"remove")])[1]
+###xpath OR operator example###
+${shopping_cart_checkout_error_message_locator} xpath=(//div[@data-qa='component cart-summary']//div[@class='spacing-top'] | //div[@data-qa='component cart-summary']//div/strong)[1]
+${shopping_cart_ajax_loader} xpath=(//cart-items-list/ajax-loader[@data-qa='component ajax-loader']//*[contains(@data-qa,'icon')] | //main//ajax-loader[contains(@data-qa,'ajax-loader')][contains(@data-qa,'cart')]//*[contains(@data-qa,'icon')])[1]
diff --git a/atest/testdata/performance/resources/pages/yves/yves_shopping_carts_page.robot b/atest/testdata/performance/resources/pages/yves/yves_shopping_carts_page.robot
new file mode 100644
index 0000000..e25282f
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_shopping_carts_page.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Resource ../../common/common_ui.robot
+*** Variables ***
+${shopping_carts_main_content_locator} xpath=//*[@data-qa='component quote-table']
+${create_shopping_cart_button} xpath=//main//a[contains(@href,'multi-cart/create')]
+${shopping_cart_name_input_field} id=quoteForm_name
+${create_new_cart_submit_button} xpath=//form[@name='quoteForm']//button[@data-qa='submit-button']
+${share_shopping_cart_confirm_button} xpath=//form[@name='shareCartForm']//button[@type='submit']
+${delete_first_shopping_cart_button} xpath=//*[@data-qa='component quote-table']//table/tbody/tr[1]//a[contains(.,'Delete')]
+
+
+*** Keywords ***
+Edit shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,'quote-table')]//tr/td[1][contains(.,'${shoppingCartName}')]/ancestor::tr/td[last()]//a[contains(@href,'update')]
+ ELSE
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Edit')]
+ END
+
+Duplicate shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Duplicate')]
+
+Add to list shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,'quote-table')]//tr/td[1][contains(.,'${shoppingCartName}')]/ancestor::tr/td[last()]//a[contains(@href,'shopping-list')]
+ ELSE
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Add to list')]
+ END
+
+Dismiss shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Dismiss')]
+
+Delete shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,'quote-table')]//tr/td[1][contains(.,'${shoppingCartName}')]/ancestor::tr/td[last()]//a[contains(@href,'delete')]
+ ELSE
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Delete')]
+ END
+
+Share shopping cart with name:
+ [Arguments] ${shoppingCartName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,'quote-table')]//tr/td[1][contains(.,'${shoppingCartName}')]/ancestor::tr/td[last()]//a[contains(@href,'share')]
+ ELSE
+ Click xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${shoppingCartName}')]/..//a[contains(.,'Share')]
+ END
+Select access level to share shopping cart with:
+ [Arguments] ${customerToShareWith} ${accessLevel}
+ IF '${env}' in ['ui_suite']
+ Select From List By Label xpath=//form[@name='shareCartForm']//div[contains(@data-qa,'user-share-list')]//li[contains(.,'${customerToShareWith}')]//select ${accessLevel}
+ ELSE
+ Select From List By Label xpath=//div[@data-qa="share-cart-table"]//*[text()='Users']/../../div[@data-qa='component user-share-list']//li[contains(.,'${customerToShareWith}')]//select ${accessLevel}
+ END
+Delete first available shopping cart
+ ${can_be_deleted}= Run Keyword And Return Status Page Should Contain Element ${delete_first_shopping_cart_button} timeout=1s
+ IF '${can_be_deleted}'=='True' Click ${delete_first_shopping_cart_button}
diff --git a/atest/testdata/performance/resources/pages/yves/yves_shopping_list_page.robot b/atest/testdata/performance/resources/pages/yves/yves_shopping_list_page.robot
new file mode 100644
index 0000000..9249dc3
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_shopping_list_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${shopping_list_main_content_locator} xpath=//*[@data-qa='component shopping-list-info']
+${add_all_available_products_to_cart_locator} xpath=//form[contains(@name,'shopping_list_add_item_to_cart_form')]//button[contains(text(),'Add all available products to cart')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/yves/yves_shopping_lists_page.robot b/atest/testdata/performance/resources/pages/yves/yves_shopping_lists_page.robot
new file mode 100644
index 0000000..3b5694f
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_shopping_lists_page.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Resource ../../common/common_ui.robot
+
+*** Variables ***
+${shopping_lists_main_content_locator} xpath=//div[@data-qa='component shopping-list-overview-table']
+${shopping_lists_page_form_locator} xpath=//form[@name='shopping_list_form']
+${shopping_list_name_input_field} id=shopping_list_form_name
+${create_shopping_list_button} xpath=//form[@name='shopping_list_form']//button[@data-qa='submit-button']
+${share_shopping_list_customers_section} xpath=//div[@data-qa="component company-dashbord-item"]//*[text()='Customer']/../../div[@data-qa='component share-list']
+${share_shopping_list_business_unit_section} xpath=//div[@data-qa="component company-dashbord-item"]//*[text()='Business Unit']/../../div[@data-qa='component share-list']
+${share_shopping_list_confirm_button} xpath=//form[@name='share_shopping_list_form']//button[@data-qa='submit-button']
+
+
+*** Keywords ***
+Select access level to share shopping list with:
+ [Arguments] ${customerToShareWith} ${accessLevel}
+ IF '${env}' in ['ui_suite']
+ Select From List By Label xpath=//form[@name='share_shopping_list_form']//div[contains(@class,'field')][contains(@class,'col')][last()]//div[contains(@data-qa,'share-list')]//li[contains(@data-qa,'list-item')][contains(.,'${customerToShareWith}')]//select ${accessLevel}
+ ELSE
+ Select From List By Label xpath=//div[@data-qa="component company-dashbord-item"]//*[text()='Customer']/../../div[@data-qa='component share-list']//li[contains(.,'${customerToShareWith}')]//select ${accessLevel}
+ END
+
+Edit shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]/ancestor::tr/td/*[contains(@data-qa,'action')]//a[contains(@href,'update')]
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]/..//div[@data-qa='component table-action-list']//a[contains(.,'Edit')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Share shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]/ancestor::tr/td/*[contains(@data-qa,'action')]//a[contains(@href,'share')]
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]/..//div[@data-qa='component table-action-list']//a[contains(.,'Share')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Print shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]/ancestor::tr/td/*[contains(@data-qa,'action')]//a[contains(@href,'print')]
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]/..//div[@data-qa='component table-action-list']//a[contains(.,'Print')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Delete shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]/ancestor::tr/td/*[contains(@data-qa,'action')]//a[contains(@href,'delete')]
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]/..//div[@data-qa='component table-action-list']//a[contains(.,'Delete')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Dismiss shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]/ancestor::tr/td/*[contains(@data-qa,'action')]//a[contains(@href,'dismiss')]
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]/..//div[@data-qa='component table-action-list']//a[contains(.,'Dismiss')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+View shopping list with name:
+ [Arguments] ${shoppingListName}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td[contains(@class,'name')][contains(.,'${shoppingListName}')]//a
+ ELSE
+ Click xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Name'][contains(.,'${shoppingListName}')]//a[contains(@href,'details')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
diff --git a/atest/testdata/performance/resources/pages/yves/yves_usercentrics_form.robot b/atest/testdata/performance/resources/pages/yves/yves_usercentrics_form.robot
new file mode 100644
index 0000000..2caeb77
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_usercentrics_form.robot
@@ -0,0 +1,5 @@
+*** Variables ****
+${usercentrics_root} id=usercentrics-root
+${usercentrics_form} ${usercentrics_root} >> css=div[data-testid='uc-banner-content']
+${usercentrics_form_accept_button} ${usercentrics_form} >> xpath=//button[@data-testid='uc-accept-all-button']
+${usercentrics_form_deny_button} ${usercentrics_form} >> xpath=//button[@data-testid='uc-deny-all-button']
diff --git a/atest/testdata/performance/resources/pages/yves/yves_wishlist_page.robot b/atest/testdata/performance/resources/pages/yves/yves_wishlist_page.robot
new file mode 100644
index 0000000..e648418
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/yves/yves_wishlist_page.robot
@@ -0,0 +1,6 @@
+*** Variables ***
+&{wishlist_main_content_locator} ui_b2b=xpath=//h1[contains(@class,'account-main')][contains(text(),'Wishlist')] ui_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Wishlist')] ui_mp_b2b=xpath=//h1[contains(@class,'account-main')][contains(text(),'Wishlist')] ui_mp_b2c=xpath=//h1[contains(@class,'account-main')][contains(text(),'Wishlist')] ui_suite=//*[@data-qa='component breadcrumb']/../*[contains(@class,'title')][contains(text(),'Wishlist')]
+${wishlist_name_input_field} id=wishlist_form_name
+${wishlist_add_new_button} xpath=//form[@name='wishlist_form']//*[@type='submit']
+${wishlist_delete_button} xpath=(//table//form[contains(@action,'wishlist/delete')]//button)
+${wishlist_add_all_to_cart_button} xpath=//form[@name='add_all_available_products_to_cart_form']/button
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_aop_bazaarvoice_details_page.robot b/atest/testdata/performance/resources/pages/zed/zed_aop_bazaarvoice_details_page.robot
new file mode 100644
index 0000000..cf94845
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_aop_bazaarvoice_details_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${pbc_bazzarvoice_client_name_input} id=credentials_clientName
+${pbc_bazzarvoice_side_id_input} id=credentials_siteId
diff --git a/atest/testdata/performance/resources/pages/zed/zed_aop_catalog_page.robot b/atest/testdata/performance/resources/pages/zed/zed_aop_catalog_page.robot
new file mode 100644
index 0000000..c742ffc
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_aop_catalog_page.robot
@@ -0,0 +1 @@
+*** Variables ***
diff --git a/atest/testdata/performance/resources/pages/zed/zed_aop_payone_datails_page.robot b/atest/testdata/performance/resources/pages/zed/zed_aop_payone_datails_page.robot
new file mode 100644
index 0000000..1f6cf9a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_aop_payone_datails_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${pbc_payone_credentials_key_input} id=credentialsKey
+${pbc_payone_merchant_id_input} id=merchantReference
+${pbc_payone_sub_account_id_input} id=subAccountReference
+${pbc_payone_payment_portal_id_input} id=paymentPortalReference
+
+
diff --git a/atest/testdata/performance/resources/pages/zed/zed_aop_pbc_details_page.robot b/atest/testdata/performance/resources/pages/zed/zed_aop_pbc_details_page.robot
new file mode 100644
index 0000000..ba06854
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_aop_pbc_details_page.robot
@@ -0,0 +1,15 @@
+*** Variables ***
+${pbc_details_main_content_locator} xpath=//app-common-details
+${pbc_datails_app_logo_locator} xpath=//img[@class='app-common-details__logo']
+${pbc_datails_short_description_locator} xpath=//app-common-details//*[contains(@class,'description')]
+${pbc_datails_author_link_locator} xpath=//app-common-details//a[contains(@class,'author-link')]
+${pbc_datails_title_locator} xpath=//app-common-details//*[contains(@class,'title-text')]
+${pbc_details_configure_button_locator} xpath=//app-common-details//spy-button[contains(@class,'configure')]
+${pbc_details_connect_button_locator} xpath=//app-common-details//spy-button[contains(@class,'connect')]
+${pbc_configuration_form_main_content_locator} xpath=//app-configuration//following-sibling::div[contains(@class,'content')]
+${pbc_details_pending_status_locator} xpath=//app-common-details//app-status-badge//*[text()='Connection pending']
+${pbc_details_connected_status_locator} xpath=//app-common-details//app-status-badge//*[text()='Connected']
+${pbc_configuration_form_save_button} xpath=//app-configuration//spy-header//spy-button[contains(@class,'save')]
+${pbc_common_details_actions_menu_button} xpath=//div[@class='app-common-details__actions']//spy-dropdown[contains(@class,'common-details')]//button
+${pbc_actions_menu_disconnect_button} xpath=//div[@class='cdk-overlay-container']//span[text()='Disconnect']
+${pbc_actions_menu_confirm_disconnect_button} xpath=//div[contains(@class,'ant-modal-content')]//button[text()='Disconnect']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_aop_usercentrics_details_page.robot b/atest/testdata/performance/resources/pages/zed/zed_aop_usercentrics_details_page.robot
new file mode 100644
index 0000000..51271ca
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_aop_usercentrics_details_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${pbc_usercentrics_integration_type_group} id=userCentricsIntegrationType
+${pbc_usercentrics_smart_data_protector_input} xpath=//input[@value="SMART_DATA_PROTECTOR"]
+${pbc_usercentrics_direct_integration_input} xpath=//input[@value="DIRECT"]
+${pbc_usercentrics_client_name_input} id=credentials_clientName
+${pbc_usercentrics_setting_id_input} id=userCentricsSettingIdentifier
+${pbc_usercentrics_is_active_input} id=isActive
diff --git a/atest/testdata/performance/resources/pages/zed/zed_attach_to_business_unit_page.robot b/atest/testdata/performance/resources/pages/zed/zed_attach_to_business_unit_page.robot
new file mode 100644
index 0000000..5ac4c0a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_attach_to_business_unit_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_business_unit_selector} xpath=//select[@id='customer_business_unit_attach_fk_company_business_unit']
diff --git a/atest/testdata/performance/resources/pages/zed/zed_availability_page.robot b/atest/testdata/performance/resources/pages/zed/zed_availability_page.robot
new file mode 100644
index 0000000..d99c6e0
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_availability_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${zed_availability_product_availability_label} xpath=//td[contains(@class,'availability')]//span[contains(@class,'label')]
+${zed_availability_never_out_of_stock_checkbox} xpath=//*[@type='checkbox' and contains(@id,'is_never_out_of_stock')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_cms_page_page.robot b/atest/testdata/performance/resources/pages/zed/zed_cms_page_page.robot
new file mode 100644
index 0000000..4096429
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_cms_page_page.robot
@@ -0,0 +1,27 @@
+*** Variables ***
+${zed_new_cms_page_create_button} xpath=//a[contains(@class,'btn-create') and contains(text(),'Create page')]
+${zed_cms_page_general_DE_store_checkbox} id=cms_page_storeRelation_id_stores_0
+${zed_cms_page_general_AT_store_checkbox} id=cms_page_storeRelation_id_stores_1
+${zed_cms_page_general_US_store_checkbox} id=cms_page_storeRelation_id_stores_2
+${zed_cms_page_general_is_searchable_checkbox} id=cms_page_isSearchable
+${zed_cms_page_general_template_dropdown} id=cms_page_fkTemplate
+${zed_cms_page_general_valid_from_datapicker} id=cms_page_validFrom
+${zed_cms_page_general_valid_to_datapicker} id=cms_page_validTo
+${zed_cms_page_general_first_locale_name_field} id=cms_page_pageAttributes_0_name
+${zed_cms_page_general_first_locale_url_field} id=cms_page_pageAttributes_0_url
+${zed_cms_page_general_second_locale_collapsed_section} xpath=(//div[@id='tab-content-general'][contains(@class,'active')]//*/ancestor::div[contains(@class,'ibox nested')])[2]//i[contains(@class,'plus')]
+${zed_cms_page_general_second_locale_expanded_section} xpath=(//div[@id='tab-content-general'][contains(@class,'active')]//*/ancestor::div[contains(@class,'ibox nested')])[2]//i[contains(@class,'minus')]
+${zed_cms_page_content_second_locale_title_collapsed_section} xpath=//div[@id='tab-content-title'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested collapsed')][2]/div/a/*[@class='ibox-tools'][1]//i[contains(@class,'plus')]
+${zed_cms_page_content_second_locale_content_collapsed_section} xpath=//div[@id='tab-content-content'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested collapsed')][2]/div/a/*[@class='ibox-tools'][1]//i[contains(@class,'plus')]
+${zed_cms_page_general_second_locale_name_field} id=cms_page_pageAttributes_1_name
+${zed_cms_page_general_second_locale_url_field} id=cms_page_pageAttributes_1_url
+${zed_cms_page_save_button} id=submit-cms
+${zed_cms_block_save_button} xpath=//input[@type='submit']
+# Placeholders
+${zed_cms_page_placeholder_title_enUS_field} xpath=//*[@id='cms_glossary_glossaryAttributes_0_translations_0_translation']/following-sibling::div//div[@class='note-editing-area']//div[@role='textbox']
+${zed_cms_page_placeholder_title_deDE_field} xpath=//*[@id='cms_glossary_glossaryAttributes_0_translations_1_translation']/following-sibling::div//div[@class='note-editing-area']//div[@role='textbox']
+${zed_cms_page_placeholder_content_enUS_field} xpath=//*[@id='cms_glossary_glossaryAttributes_1_translations_0_translation']/following-sibling::div//div[@class='note-editing-area']//div[@role='textbox']
+${zed_cms_page_placeholder_content_deDE_field} xpath=//*[@id='cms_glossary_glossaryAttributes_1_translations_1_translation']/following-sibling::div//div[@class='note-editing-area']//div[@role='textbox']
+# Action buttons
+${zed_cms_page_publish_button}= xpath=//button[@type='submit' and contains(.,'Publish')]
+${zed_cms_page_activate_button}= xpath=//button[contains(@class,'submit') and contains(.,'Activate')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_company_business_unit_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_company_business_unit_page.robot
new file mode 100755
index 0000000..4fb46a5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_company_business_unit_page.robot
@@ -0,0 +1,8 @@
+*** Variables ***
+${zed_bu_company_dropdown_with_search_locator} xpath=//span[@id='select2-company-business-unit_fk_company-container']
+${zed_bu_company_dropdown_locator} id=company-business-unit_fk_company
+${zed_bu_parent_bu_dropdown_locator} id=company-business-unit_fk_parent_company_business_unit
+${zed_bu_company_search_field} xpath=//input[@type='search'][contains(@aria-controls,'company-business-unit')]
+${zed_bu_name_field} id=company-business-unit_name
+${zed_bu_iban_field} id=company-business-unit_iban
+${zed_bu_bic_field} id=company-business-unit_bic
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_company_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_company_page.robot
new file mode 100755
index 0000000..a287ec4
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_company_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_company_name_input_field} id=company_name
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_company_role_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_company_role_page.robot
new file mode 100755
index 0000000..f99a855
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_company_role_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${zed_role_company_dropdown_with_search_locator} id=select2-company_role_create_form_fkCompany-container
+${zed_role_company_dropdown_locator} id=company_role_create_form_fkCompany
+${zed_role_company_search_field} xpath=//input[@type='search'][contains(@aria-controls,'company_role')]
+${zed_role_name_field} id=company_role_create_form_name
+${zed_role_is_default_checkbox} id=company_role_create_form_isDefault
+
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_company_user_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_company_user_page.robot
new file mode 100755
index 0000000..0306cea
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_company_user_page.robot
@@ -0,0 +1,12 @@
+*** Variables ***
+${zed_create_company_user_email_field} id=company-user_customer_email
+${zed_create__company_user_salutation_dropdown} id=company-user_customer_salutation
+${zed_create_company_user_first_name_field} id=company-user_customer_first_name
+${zed_create_company_user_last_name_field} id=company-user_customer_last_name
+${zed_create_company_user_gender_dropdown} id=company-user_customer_gender
+${zed_create_company_user_dob_picker} id=company-user_customer_date_of_birth
+${zed_create_company_user_phone_field} id=company-user_customer_phone
+${zed_create_company_user_company_name_dropdown} id=select2-company-user_fk_company-container
+${zed_create_company_user_company_search_field} xpath=//input[@type='search'][contains(@aria-controls,'company-results')]
+${zed_create_company_business_unit_dropdown} id=select2-company-user_fk_company_business_unit-container
+${zed_create_company_business_unit_search_field} xpath=//input[@type='search'][contains(@aria-controls,'business_unit-results')]
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_merchant_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_merchant_page.robot
new file mode 100644
index 0000000..87969bb
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_merchant_page.robot
@@ -0,0 +1,16 @@
+*** Variables ***
+${zed_create_merchant_name_field} id=merchant_name
+${zed_create_merchant_reference_field} id=merchant_merchant_reference
+${zed_create_merchant_email_field} id=merchant_email
+${zed_create_merchant_url_en_locale_field} id=merchant_urlCollection_0_url
+${zed_create_merchant_url_de_locale_field} id=merchant_urlCollection_1_url
+${zed_create_merchant_contact_first_name} id=merchant_merchantProfile_contact_person_first_name
+${zed_create_merchant_contact_last_name} id=merchant_merchantProfile_contact_person_last_name
+
+${zed_create_merchant_user_email_field} id=merchant-user_username
+${zed_create_merchant_user_first_name_field} id=merchant-user_firstName
+${zed_create_merchant_user_last_name_field} id=merchant-user_lastName
+${zed_add_merchant_user_button} xpath=//a[contains(@class,'btn-create')][contains(text(),'User')]
+
+${zed_merchant_user_search_field_locator} xpath=//div[@class='dataTables_filter']//input[@type='search']
+
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_return_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_return_page.robot
new file mode 100644
index 0000000..fb3c1a7
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_return_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${zed_create_return_main_content_locator} xpath=//form[@name='return_create_form']
+${zed_create_return_button} xpath=//form[@name='return_create_form']/button[contains(@class,'create-return')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_create_zed_user_page.robot b/atest/testdata/performance/resources/pages/zed/zed_create_zed_user_page.robot
new file mode 100644
index 0000000..6c4ce03
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_create_zed_user_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${zed_user_email_field} id=user_username
+${zed_user_password_filed} id=user_password_first
+${zed_user_repeat_password_field} id=user_password_second
+${zed_user_first_name_field} id=user_first_name
+${zed_user_last_name_field} id=user_last_name
+${zed_user_interface_language} id=user_fk_locale
diff --git a/atest/testdata/performance/resources/pages/zed/zed_customer_page.robot b/atest/testdata/performance/resources/pages/zed/zed_customer_page.robot
new file mode 100644
index 0000000..619d0b9
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_customer_page.robot
@@ -0,0 +1,28 @@
+*** Variables ***
+${zed_customer_edit_page_title} xpath=//h5[contains(text(),'Edit Customer')]
+${zed_customer_delete_button} xpath=//a[contains(@class,'btn btn-sm btn-outline safe-submit btn-remove')]
+${zed_customer_delete_confirm_button} xpath=//button[contains(@class,'btn btn-danger safe-submit')]
+${zed_customer_edit_salutation_select} id=customer_salutation
+${zed_customer_edit_first_name_field} id=customer_first_name
+${zed_customer_edit_last_name_field} id=customer_last_name
+${zed_customer_edit_address_salutation_select} id=customer_address_salutation
+${zed_customer_edit_address_first_name_field} id=customer_address_first_name
+${zed_customer_edit_address_last_name_field} id=customer_address_last_name
+${zed_customer_edit_address_address_1_field} id=customer_address_address1
+${zed_customer_edit_address_address_2_field} id=customer_address_address2
+${zed_customer_edit_address_address_3_field} id=customer_address_address3
+${zed_customer_edit_address_city_field} id=customer_address_city
+${zed_customer_edit_address_zip_code_field} id=customer_address_zip_code
+${zed_customer_edit_address_country_select} id=customer_address_fk_country
+${zed_customer_edit_address_phone_field} id=customer_address_phone
+${zed_customer_edit_address_company_field} id=customer_address_company
+${zed_customer_edit_address_submit_button} xpath=//form[@name='customer_address']//*[@type='submit']
+${zed_edit_company_user_salutation} id=company-user_customer_salutation
+${zed_edit_company_user_first_name} id=company-user_customer_first_name
+${zed_edit_company_user_last_name} id=company-user_customer_last_name
+${zed_edit_company_user_company_select} id=company-user_fk_company
+${zed_edit_company_user_company_span} id=select2-company-user_fk_company-container
+${zed_edit_company_user_business_unit_select} id=company-user_fk_company_business_unit
+${zed_edit_company_user_business_unit_span} id=select2-company-user_fk_company_business_unit-container
+${zed_edit_company_user_search_select_field} xpath=//input[@type='search']
+${zed_attach_customer_to_bu_business_unit_span} id=select2-customer_business_unit_attach_fk_company_business_unit-container
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_dashboard_page.robot b/atest/testdata/performance/resources/pages/zed/zed_dashboard_page.robot
new file mode 100644
index 0000000..7e91d48
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_dashboard_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${dashboard_count_orders_graph} id=chart-count-orders
+${dashboard_orders_by_status_graph} id=chart-status-orders
+${dashboard_top_orders_graph} id=chart-top-orders
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_data_exchange_api_configurator_page.robot b/atest/testdata/performance/resources/pages/zed/zed_data_exchange_api_configurator_page.robot
new file mode 100644
index 0000000..c77b795
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_data_exchange_api_configurator_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${data_exchange_table_select_locator} id=dynamic-entity_table_name
+${data_exchange_resource_name_field} id=dynamic-entity_table_alias
+${data_exchange_create_configuration_button} xpath=//button[contains(@class,'safe-submit')]
+${data_exchange_download_spec_button} xpath=//a[contains(@href,'documentation/download')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_delete_company_user_page.robot b/atest/testdata/performance/resources/pages/zed/zed_delete_company_user_page.robot
new file mode 100644
index 0000000..96cd92b
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_delete_company_user_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_confirm_delete_company_user_button} xpath=//form[@name='delete_company_user_form']/input[@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_delete_user_confirmation_page.robot b/atest/testdata/performance/resources/pages/zed/zed_delete_user_confirmation_page.robot
new file mode 100644
index 0000000..d2f03c1
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_delete_user_confirmation_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_confirm_delete_user_button} xpath=//form[@name='delete_confirm_form']/input[@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_discount_page.robot b/atest/testdata/performance/resources/pages/zed/zed_discount_page.robot
new file mode 100644
index 0000000..4f78685
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_discount_page.robot
@@ -0,0 +1,27 @@
+*** Variables ***
+${zed_discount_add_new_discount_button} xpath=//a[contains(@class,'btn') and contains(text(),'Create new discount')]
+${zed_discount_create_discount_page} xpath=//form[contains(@id,'discount-form')]/ancestor::div//*[contains(text(),'Create new discount')]
+${zed_discount_type_dropdown} id=discount_discountGeneral_discount_type
+${zed_discount_name_field} id=discount_discountGeneral_display_name
+${zed_discount_description_field} id=discount_discountGeneral_description
+${zed_discount_valid_from_field} id=discount_discountGeneral_valid_from
+${zed_discount_valid_to_field} id=discount_discountGeneral_valid_to
+${zed_discount_calculator_type_drop_down} id=discount_discountCalculator_calculator_plugin
+${zed_discount_percentage_value_field} id=discount_discountCalculator_amount
+${zed_discount_euro_gross_field} id=discount_discountCalculator_moneyValueCollection_1_gross_amount
+${zed_discount_plain_query_apply_to__button} id=btn-calculation-get
+${zed_discount_plain_query_apply_to_field} id=discount_discountCalculator_collector_query_string
+${zed_discount_query_builder_first_calculation_group} id=builder_calculation_group_0
+${zed_discount_query_builder_first_condition_group} id=builder_condition_group_0
+${zed_discount_promotional_product_radio} id=discount_discountCalculator_collectorStrategyType_1
+${zed_discount_promotional_product_abstract_sku_field} id=discount_discountCalculator_discountPromotion_abstractSkus
+${zed_discount_promotional_product_abstract_quantity_field} id=discount_discountCalculator_discountPromotion_quantity
+${zed_discount_activate_button} xpath=//button[contains(@type,'submit') and contains(.,'Activate')]
+${zed_discount_voucher_quantity_field} id=discount_voucher_quantity
+${zed_discount_voucher_custom_code_field} id=discount_voucher_custom_code
+${zed_discount_voucher_max_usages_field} id=discount_voucher_max_number_of_uses
+${zed_discount_random_length_dropdown} id=discount_voucher_random_generated_code_length
+${zed_discount_voucher_code_generate_button} id=discount_voucher_generate
+${zed_discount_save_button} xpath=//input[@type='button' and contains(@class,'create')]
+${zed_discount_plain_query_apply_when__button} id=btn-condition-get
+${zed_discount_plain_query_apply_when_field} id=discount_discountCondition_decision_rule_query_string
diff --git a/atest/testdata/performance/resources/pages/zed/zed_edit_global_threshold_page.robot b/atest/testdata/performance/resources/pages/zed/zed_edit_global_threshold_page.robot
new file mode 100644
index 0000000..c44ec8a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_edit_global_threshold_page.robot
@@ -0,0 +1,17 @@
+*** Variables ***
+${zed_global_threshold_store_currency_select} id=global-threshold_storeCurrency
+${zed_global_threshold_store_currency_span} id=select2-global-threshold_storeCurrency-container
+${zed_global_threshold_minimum_hard_value_input} id=global-threshold_hardThreshold_threshold
+${zed_global_threshold_minimum_hard_en_message_input} id=global-threshold_hardThreshold_en_US_message
+${zed_global_threshold_minimum_hard_de_message_input} id=global-threshold_hardThreshold_de_DE_message
+${zed_global_threshold_minimum_hard_second_locale_collapce_section} xpath=//input[@id='global-threshold_hardThreshold_threshold']/../../div[contains(@class,'ibox nested collapsed')]//i[contains(@class,'plus')]
+${zed_global_threshold_maximum_hard_value_input} id=global-threshold_hardMaximumThreshold_threshold
+${zed_global_threshold_maximum_hard_en_message_input} id=global-threshold_hardMaximumThreshold_en_US_message
+${zed_global_threshold_maximum_hard_de_message_input} id=global-threshold_hardMaximumThreshold_de_DE_message
+${zed_global_threshold_maximum_hard_second_locale_collapce_section} xpath=//input[@id='global-threshold_hardMaximumThreshold_threshold']/../../div[contains(@class,'ibox nested collapsed')]//i[contains(@class,'plus')]
+${zed_global_threshold_soft_value_input} id=global-threshold_softThreshold_threshold
+${zed_global_threshold_soft_en_message_input} id=global-threshold_softThreshold_en_US_message
+${zed_global_threshold_soft_de_message_input} id=global-threshold_softThreshold_de_DE_message
+${zed_global_threshold_soft_second_locale_collapce_section} xpath=//input[@id='global-threshold_softThreshold_de_DE_message']/../../../../div[contains(@class,'ibox nested collapsed')]//i[contains(@class,'plus')]
+${zed_global_threshold_soft_fixed_fee_value_input} id=global-threshold_softThreshold_fixedFee
+${zed_global_threshold_soft_flexible_fee_value_input} id=global-threshold_softThreshold_flexibleFee
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_edit_product_page.robot b/atest/testdata/performance/resources/pages/zed/zed_edit_product_page.robot
new file mode 100644
index 0000000..cf32815
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_edit_product_page.robot
@@ -0,0 +1,35 @@
+*** Variables ***
+${zed_pdp_abstract_main_content_locator} css=*[name=product_form_edit]
+${zed_pdp_concrete_main_content_locator} css=*[name=product_concrete_form_edit]
+${zed_pdp_add_concrete_main_content_locator} css=*[name=product_concrete_form_add]
+${zed_pdp_discontinue_button} xpath=//form[@name='product_concrete_form_edit']//div[@id='tab-content-discontinue']//a[contains(@href,'discontinue')]
+${zed_pdp_add_products_alternative_input} xpath=//form[@name='product_concrete_form_edit']//div[@id='tab-content-alternatives']//input
+${zed_pdp_alternative_products_suggestion} xpath=//ul[@id='select2-product_concrete_form_edit_alternative_products-results']/li[contains(@class,'select2-results__option')]
+${zed_pdp_restore_button} xpath=//form[@name='product_concrete_form_edit']//div[@id='tab-content-discontinue']//a[contains(@href,'restore')]
+${zed_pdp_save_button} xpath=//input[@type='submit' and @value='Save']
+${zed_product_variant_table_processing_locator} xpath=//div[@id='product-variant-table_processing']
+${zed_product_edit_name_en_input} xpath=//input[@id='product_form_edit_general_en_US_name']
+${zed_product_edit_name_de_input} xpath=//input[@id='product_form_edit_general_de_DE_name']
+${zed_product_edit_new_from} xpath=//input[@id='product_form_edit_new_from']
+${zed_product_edit_new_to} xpath=//input[@id='product_form_edit_new_to']
+${zed_product_general_second_locale_collapsed_section} xpath=//div[@id='tab-content-general'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested collapsed')]//i[contains(@class,'plus')]
+${zed_product_general_second_locale_expanded_section} xpath=//div[@id='tab-content-general'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested collapsed')]//i[contains(@class,'minus')]
+${zed_product_add_sku_input} id=product_form_add_sku
+${zed_product_add_name_en_input} id=product_form_add_general_en_US_name
+${zed_product_add_name_de_input} id=product_form_add_general_de_DE_name
+${zed_product_add_new_from} id=product_form_add_new_from
+${zed_product_add_new_to} id=product_form_add_new_to
+${zed_product_tax_set_select} xpath=//select[contains(@id,'product_form')][contains(@id,'tax_rate')]
+${zed_pdp_concrete_name_en_input} id=product_concrete_form_edit_general_en_US_name
+${zed_pdp_concrete_name_de_input} id=product_concrete_form_edit_general_de_DE_name
+${zed_pdp_concrete_valid_from} id=product_concrete_form_edit_valid_from
+${zed_pdp_concrete_valid_to} id=product_concrete_form_edit_valid_to
+${zed_pdp_concrete_searchable_en} id=product_concrete_form_edit_general_en_US_is_searchable
+${zed_pdp_concrete_searchable_de} id=product_concrete_form_edit_general_de_DE_is_searchable
+${zed_add_concrete_sku_field} id=sku-input
+${zed_add_concrete_name_en_input} id=product_concrete_form_add_general_en_US_name
+${zed_add_concrete_name_de_input} id=product_concrete_form_add_general_de_DE_name
+${zed_add_concrete_valid_from} id=product_concrete_form_add_valid_from
+${zed_add_concrete_valid_to} id=product_concrete_form_add_valid_to
+${zed_add_concrete_use_price_from_abstract} id=price-source-checkbox
+${zed_add_concrete_autogenerate_sku} id=sku-autogenerate-checkbox-input
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_edit_warehouse_page.robot b/atest/testdata/performance/resources/pages/zed/zed_edit_warehouse_page.robot
new file mode 100644
index 0000000..5b4db41
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_edit_warehouse_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_warehouse_name} id=stock_name
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_glossary_page.robot b/atest/testdata/performance/resources/pages/zed/zed_glossary_page.robot
new file mode 100644
index 0000000..d36d438
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_glossary_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${zed_translation_name} id=translation_glossary_key
+${zed_translation_EN_US} id=translation_locales_en_US
+${zed_translation_DE_DE} id=translation_locales_de_DE
+${zed_translation_edit} xpath=//a[contains(@href,'/glossary/edit')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_login_page.robot b/atest/testdata/performance/resources/pages/zed/zed_login_page.robot
new file mode 100755
index 0000000..0b4767a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_login_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${zed_user_name_field} id=auth_username
+${zed_password_field} id=auth_password
+${zed_login_button} xpath=//button[@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_marketplace_offers_page.robot b/atest/testdata/performance/resources/pages/zed/zed_marketplace_offers_page.robot
new file mode 100644
index 0000000..58d32a5
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_marketplace_offers_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_merchants_filter} xpath=//select[@name='id-merchant']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_order_details_page.robot b/atest/testdata/performance/resources/pages/zed/zed_order_details_page.robot
new file mode 100644
index 0000000..573eeda
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_order_details_page.robot
@@ -0,0 +1,19 @@
+*** Variables ***
+${order_details_billing_address} xpath=//div[@id='customer']//div[contains(@class,'content')]//dd[last()]
+${create_shipment_button} xpath=//a[contains(@href,'/shipment-gui/create')]
+${create_shipment_delivery_address_dropdown} id=shipment_group_form_shipment_shippingAddress_idCustomerAddress
+${create_shipment_salutation_dropdown} id=shipment_group_form_shipment_shippingAddress_salutation
+${create_shipment_first_name_field} id=shipment_group_form_shipment_shippingAddress_firstName
+${create_shipment_last_name_field} id=shipment_group_form_shipment_shippingAddress_lastName
+${create_shipment_email_field} id=shipment_group_form_shipment_shippingAddress_email
+${create_shipment_country_dropdown} id=shipment_group_form_shipment_shippingAddress_iso2Code
+${create_shipment_address_1_field} id=shipment_group_form_shipment_shippingAddress_address1
+${create_shipment_address_2_field} id=shipment_group_form_shipment_shippingAddress_address2
+${create_shipment_city_field} id=shipment_group_form_shipment_shippingAddress_city
+${create_shipment_zip_code_field} id=shipment_group_form_shipment_shippingAddress_zipCode
+${create_shipment_shipment_method} id=shipment_group_form_shipment_method_idShipmentMethod
+${create_shipment_requested_delivery_date} id=shipment_group_form_shipment_requestedDeliveryDate
+${zed_order_details_page_comments} xpath=//p[@class="comment-title"]//following-sibling::p
+${create_shipment_button} xpath=//a[contains(@href,'shipment-gui/create?')]
+${edit_shipment_button} xpath=//a[contains(@href,'shipment-gui/edit?')]
+${zed_order_details_main_content_locator} id=customer
diff --git a/atest/testdata/performance/resources/pages/zed/zed_order_shipment_page.robot b/atest/testdata/performance/resources/pages/zed/zed_order_shipment_page.robot
new file mode 100644
index 0000000..0c06fa2
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_order_shipment_page.robot
@@ -0,0 +1,11 @@
+*** Variables ***
+${shipment_address_first_name} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_firstName']
+${shipment_address_last_name} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_lastName']
+${shipment_address_email} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_email']
+${shipment_address_address1} xpath=//input[@id="shipment_group_form_shipment_shippingAddress_address1"]
+${shipment_address_address2} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_address2']
+${shipment_address_city} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_city']
+${shipment_address_zipcode} xpath=//input[@id='shipment_group_form_shipment_shippingAddress_zipCode']
+${delivery_address_shipment_page} xpath=//select[@id='shipment_group_form_shipment_shippingAddress_idCustomerAddress']
+${salutation_shipment_page} xpath=//select[@id='shipment_group_form_shipment_shippingAddress_salutation']
+${save_button_shipment_page} xpath=//input[@type="submit"]
diff --git a/atest/testdata/performance/resources/pages/zed/zed_payment_methods_page.robot b/atest/testdata/performance/resources/pages/zed/zed_payment_methods_page.robot
new file mode 100644
index 0000000..347125e
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_payment_methods_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${zed_payment_methods_edit_active_checkbox} id=payment_method_form_isActive
+${zed_payment_methods_edit_save_btn} id=submit-payment-method
diff --git a/atest/testdata/performance/resources/pages/zed/zed_product_list_page.robot b/atest/testdata/performance/resources/pages/zed/zed_product_list_page.robot
new file mode 100644
index 0000000..d8015fe
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_product_list_page.robot
@@ -0,0 +1,6 @@
+*** Variables ***
+${zed_product_list_title_field} id=productListAggregate_productList_title
+${zed_product_list_type_whitelist_radio} xpath=//input[@id='productListAggregate_productList_type_0']
+${zed_product_list_type_blacklist_radio} xpath=//input[@id='productListAggregate_productList_type_1']
+${zed_product_list_categories_search_field} xpath=//input[contains(@class,'select2-search')]
+${zed_product_list_confirm_removal_button} xpath=//form[@name='delete_product_list_form']//input[@type='submit']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_product_set_page.robot b/atest/testdata/performance/resources/pages/zed/zed_product_set_page.robot
new file mode 100644
index 0000000..ff690c3
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_product_set_page.robot
@@ -0,0 +1,12 @@
+*** Variables ***
+${zed_product_set_name_en_field} id=product_set_form_general_form_localized_general_form_collection_0_name
+${zed_product_set_url_en_field} id=product_set_form_general_form_localized_general_form_collection_0_url
+${zed_product_set_copy_en_name_button} xpath=//div[@id='tab-content-general']//div[@class='panel-body']//div[@class='form-group']//div[@id='localized_attributes_container-en_US']//div[@class='ibox-content']//div[contains(@class,'form-group')]//div[@class='input-group']//span[@class='input-group-btn']//button[@type='button']
+${zed_product_set_name_de_field} id=product_set_form_general_form_localized_general_form_collection_1_name
+${zed_product_set_url_de_field} id=product_set_form_general_form_localized_general_form_collection_1_url
+${zed_product_set_key_field} id=product_set_form_general_form_product_set_key
+${zed_product_set_is_active_checkbox} id=product_set_form_general_form_is_active
+${zed_product_set_search_product_table_field} xpath=//div[@id='product-table_filter']//input[@type='search']
+${zed_product_set_search_product_table_select_first_checkbox} xpath=(//input[contains(@id,'all_products_checkbox')])[1]
+${zed_product_set_general_second_locale_collapsed_section} xpath=(//div[@id='tab-content-general'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested')]//i[contains(@class,'plus')])[2]
+${zed_product_set_general_second_locale_expanded_section} xpath=(//div[@id='tab-content-general'][contains(@class,'active')]//ancestor::div[contains(@class,'ibox nested')]//i[contains(@class,'minus')])[2]
diff --git a/atest/testdata/performance/resources/pages/zed/zed_return_details_page.robot b/atest/testdata/performance/resources/pages/zed/zed_return_details_page.robot
new file mode 100644
index 0000000..ccd82ed
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_return_details_page.robot
@@ -0,0 +1,2 @@
+*** Variables ***
+${zed_return_details_main_content_locator} xpath=//table[@data-qa='return-items-table']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_root_menus_page.robot b/atest/testdata/performance/resources/pages/zed/zed_root_menus_page.robot
new file mode 100644
index 0000000..4d62993
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_root_menus_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${zed_first_navigation_menus_locator} xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'/') and not (contains(@href,'javascript'))])
+${zed_root_menu_icons_locator} xpath=//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a
+${zed_second_navigation_menus_locator} xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')])
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_shipment_page.robot b/atest/testdata/performance/resources/pages/zed/zed_shipment_page.robot
new file mode 100644
index 0000000..ece417b
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_shipment_page.robot
@@ -0,0 +1,5 @@
+*** Variables ***
+${shipment_method_dropdown} id=shipment_group_form_shipment_method_idShipmentMethod
+${view_order_last_placed} xpath=(//a[starts-with(@href,'/sales/detail')])[1]
+${country_create_new_shipment_page} xpath=(//select[@id='shipment_group_form_shipment_shippingAddress_iso2Code'])[1]
+${shipment_method_dropdown_new_shipment_page} xpath=//select[@id='shipment_group_form_shipment_method_idShipmentMethod']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_store_page.robot b/atest/testdata/performance/resources/pages/zed/zed_store_page.robot
new file mode 100644
index 0000000..34432f0
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_store_page.robot
@@ -0,0 +1,12 @@
+*** Variables ***
+${zed_store_add_name_input} xpath=//input[@id="store_name"]
+${zed_store_save_button} xpath=//input[@type="submit"]
+${zed_store_locale_tab} xpath=//ul[contains(@class, 'nav')]/li[contains(@data-tab-content-id, 'locale_store_relation')]
+${zed_store_default_locale_iso_code} xpath=//select[contains(@id,"defaultLocaleIsoCode")]
+${zed_store_currency_tab} xpath=//ul[contains(@class, 'nav')]/li[contains(@data-tab-content-id, 'locale_currency_relation')]
+${zed_store_default_currency_iso_code} xpath=//select[contains(@id,"defaultCurrencyIsoCode")]
+${zed_store_delivery_region_tab} xpath=//ul[contains(@class, 'nav')]/li[contains(@data-tab-content-id, 'country_store_relation')]
+${zed_store_context_tab} xpath=//ul[contains(@class, 'nav')]/li[contains(@data-tab-content-id, 'store_context')]
+${zed_store_context_add_button} xpath=//a[contains(@class, 'add-store-contex')] | //button[contains(@class, 'add-store-contex')]
+${zed_store_context_select} xpath=//select[contains(@id, 'store_contextCollection_contexts_1_timezone')] | //select[contains(@id, 'store_applicationContextCollection_applicationContexts_1_timezone')]
+${zed_store_search_field} xpath=//form[@name='store']/div/div[@class='tab-content']/div[contains(@id,'tab-content')][contains(@class,'active')]//*[contains(@id,'available')]//input[@type='search']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_user_group_page.robot b/atest/testdata/performance/resources/pages/zed/zed_user_group_page.robot
new file mode 100644
index 0000000..d0485a4
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_user_group_page.robot
@@ -0,0 +1,3 @@
+*** Variables ***
+${zed_user_group_title} id=group_title
+${zed_user_group_assigned_role_textbox} xpath=//input[@role='searchbox']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_user_role_page.robot b/atest/testdata/performance/resources/pages/zed/zed_user_role_page.robot
new file mode 100644
index 0000000..f5953ca
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_user_role_page.robot
@@ -0,0 +1,7 @@
+*** Variables ***
+${zed_user_role_name} id=role_name
+${zed_user_role_bundle_locator} id=ruleset_bundle
+${zed_user_role_controller_locator} id=ruleset_controller
+${zed_user_role_action_locator} id=ruleset_action
+${zed_user_role_permission} id=ruleset_type
+${zed_user_add_rule_button} xpath=//form[@name='ruleset']//input[contains(@class,'safe-submit')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_view_abstract_product_page.robot b/atest/testdata/performance/resources/pages/zed/zed_view_abstract_product_page.robot
new file mode 100644
index 0000000..a318b5a
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_view_abstract_product_page.robot
@@ -0,0 +1,9 @@
+*** Variables ***
+${zed_view_abstract_product_main_content_locator} xpath=//a[@href='/product-management'][contains(@class,'btn-view')]
+${zed_view_abstract_product_merchant} xpath=(//div[@class='ibox-content']/div[@class='row'])[1]/div[2]
+${zed_view_abstract_product_status} xpath=(//div[@class='ibox-content']/div[@class='row'])[2]/div[2]/span
+&{zed_view_abstract_product_store} ui_mp_b2b=xpath=(//div[@class='ibox-content']/div[@class='row'])[3]/div[2] ui_mp_b2c=xpath=(//div[@class='ibox-content']/div[@class='row'])[3]/div[2] ui_b2b=xpath=(//div[@class='ibox-content']/div[@class='row'])[1]/div[2] ui_b2c=xpath=(//div[@class='ibox-content']/div[@class='row'])[1]/div[2] ui_suite=xpath=(//div[@class='ibox-content']/div[@class='row'])[contains(.,'elation')]//div[2]
+&{zed_view_abstract_product_sku} ui_mp_b2b=xpath=(//div[@class='ibox-content']/div[@class='row'])[4]/div[2] ui_mp_b2c=xpath=(//div[@class='ibox-content']/div[@class='row'])[4]/div[2] ui_b2c=xpath=(//div[@class='ibox-content']/div[@class='row'])[2]/div[2] ui_b2b=xpath=(//div[@class='ibox-content']/div[@class='row'])[2]/div[2] ui_suite=xpath=(//div[@class='ibox-content']/div[@class='row'])[contains(.,'SKU')]//div[2]
+&{zed_view_abstract_product_name} ui_mp_b2b=xpath=(//div[@class='ibox-content']/div[@class='row'])[6]/div[2] ui_mp_b2c=xpath=(//div[@class='ibox-content']/div[@class='row'])[6]/div[2] ui_b2b=xpath=//div[@class='m-t']//a[contains(.,'en_')]//../..//div[@class='row'][1]/div[2] ui_b2c=xpath=//div[@class='m-t']//a[contains(.,'en_')]//../..//div[@class='row'][1]/div[2] ui_suite=xpath=((//div[@class='ibox-content']/div[@class='row'])[contains(.,'Name')]//div[2])[1]
+${zed_view_abstract_general_second_locale_collapsed_section} xpath=//div[@class='m-t']//div[@class='ibox-tools']//i[contains(@class,'plus')]
+${zed_view_abstract_general_second_locale_expanded_section} //div[@class='m-t']//div[@class='ibox-tools']//i[contains(@class,'minus')]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_view_concrete_product_page.robot b/atest/testdata/performance/resources/pages/zed/zed_view_concrete_product_page.robot
new file mode 100644
index 0000000..cf38878
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_view_concrete_product_page.robot
@@ -0,0 +1,4 @@
+*** Variables ***
+${zed_view_concrete_product_main_content_locator} xpath=//a[@href='/product-management'][contains(@class,'btn-view')]
+${zed_view_concrete_product_sku} xpath=(//div[@class='ibox-content']/div[@class='row'])[1]/div[2]
+${zed_view_concrete_product_name} xpath=(//div[@class='ibox-content']/div[@class='row'])[3]/div[2]
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/pages/zed/zed_view_offer_page.robot b/atest/testdata/performance/resources/pages/zed/zed_view_offer_page.robot
new file mode 100644
index 0000000..2aa20c2
--- /dev/null
+++ b/atest/testdata/performance/resources/pages/zed/zed_view_offer_page.robot
@@ -0,0 +1,11 @@
+*** Variables ***
+${zed_view_offer_page_main_content_locator} xpath=//a[contains(@class,'btn-view')][@href='/product-offer-gui/list']
+${zed_view_offer_approval_status} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[2]/div[2]/span
+${zed_view_offer_status} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[3]/div[2]/span
+${zed_view_offer_store} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[4]/div[2]/span
+${zed_view_offer_sku} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[5]/div[2]/a
+${zed_view_offer_name} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[7]/div[2]
+${zed_view_offer_merchant} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[11]/div[2]/a
+${zed_view_offer_merchant_sku} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[12]/div[2]
+${zed_view_offer_services} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[15]/div
+${zed_view_offer_shipment_types} xpath=(//div[@class='ibox-content']/div[contains(@class,'row')])[16]/div
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/agent_assist_steps.robot b/atest/testdata/performance/resources/steps/agent_assist_steps.robot
new file mode 100644
index 0000000..0aa68e1
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/agent_assist_steps.robot
@@ -0,0 +1,65 @@
+*** Settings ***
+Resource ../pages/zed/zed_create_zed_user_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/yves/yves_agent_assist_page.robot
+
+*** Keywords ***
+Zed: create new Zed user with the following data:
+ [Arguments] ${zedUserEmail} ${zedUserPassword} ${zedUserFirstName} ${zedUserLastName} ${checkboxGroup} ${checkboxAgent} ${userInterfaceLanguage}
+ ${currentURL}= Get Location
+ IF '/user' not in '${currentURL}' Zed: go to URL: /user
+ IF '${env}' in ['ui_mp_b2b']
+ Zed: click button in Header: Add New User
+ ELSE
+ Zed: click button in Header: Add New User
+ END
+ Wait Until Element Is Visible ${zed_user_email_field}
+ Type Text ${zed_user_email_field} ${zedUserEmail}
+ Type Text ${zed_user_password_filed} ${zedUserPassword}
+ Type Text ${zed_user_repeat_password_field} ${zedUserPassword}
+ Type Text ${zed_user_first_name_field} ${zedUserFirstName}
+ Type Text ${zed_user_last_name_field} ${zedUserLastName}
+ Zed: Check checkbox by Label: ${checkboxGroup}
+ Zed: Check checkbox by Label: ${checkboxAgent}
+ Select From List By Label ${zed_user_interface_language} ${userInterfaceLanguage}
+ Zed: submit the form
+ IF '${env}' in ['ui_mp_b2b']
+ Zed: wait for button in Header to be visible: Add New User ${browser_timeout}
+ ELSE
+ Zed: wait for button in Header to be visible: Add New User ${browser_timeout}
+ END
+ Zed: table should contain: ${zedUserEmail}
+
+Yves: perform search by customer:
+ [Arguments] ${searchQuery}
+ Type Text ${agent_customer_search_widget} ${searchQuery} delay=10ms
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: agent widget contains:
+ [Arguments] ${searchQuery}
+ Wait Until Element Is Visible xpath=//ul[@data-qa='component customer-list']/li[@data-value='${searchQuery}']
+ Page Should Contain Element xpath=//ul[@data-qa='component customer-list']/li[@data-value='${searchQuery}']
+
+Yves: as an agent login under the customer:
+ [Arguments] ${searchQuery}
+ Fill Text ${agent_customer_search_widget} ${EMPTY} force=True
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: perform search by customer: ${searchQuery}
+ Wait Until Element Is Visible //ul[@data-qa='component customer-list']/li[@data-value='${searchQuery}']
+ Click xpath=//ul[@data-qa='component customer-list']/li[@data-value='${searchQuery}']
+ Click ${agent_confirm_login_button}
+
+Yves: end customer assistance
+ Click ${end_customer_assistance}
+
+Yves: logout as an agent
+ Click ${agent_logout}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/api_dynamic_entity_steps.robot b/atest/testdata/performance/resources/steps/api_dynamic_entity_steps.robot
new file mode 100644
index 0000000..14fa6ed
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/api_dynamic_entity_steps.robot
@@ -0,0 +1,128 @@
+*** Settings ***
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Create api key in db
+ [Documentation] This keyword creates api key hash for data exchange api in the DB table spy_api_key. Key hash is static and matches env variable `dummy_api_key`.
+ ...
+ ... Each combination of `dummy_api_key` and `dummy_key_hash` is unique
+ ...
+ ### works for MariaDB and PostgreSQL ###
+ [Arguments] ${key_hash}=${dummy_key_hash} ${created_by}=1
+ Connect to Spryker DB
+ ${hash_id}= Query select id_api_key from spy_api_key WHERE key_hash='${key_hash}';
+ ${hash_id_length}= Get Length ${hash_id}
+ IF ${hash_id_length} > 0
+ Execute Sql String DELETE FROM spy_api_key WHERE key_hash='${key_hash}';
+ END
+ ${new_id}= Get next id from table spy_api_key id_api_key
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert into spy_api_key (id_api_key, name, key_hash, created_by) value ('${new_id}', 'autotest${random}', '${key_hash}', '${created_by}');
+ ELSE
+ Execute Sql String insert into spy_api_key (id_api_key, name, key_hash, created_by) values ('${new_id}', 'autotest${random}', '${key_hash}', '${created_by}');
+ END
+ Disconnect From Database
+
+Delete api key from db
+ [Documentation] This keyword deletes api key hash for data exchange api in the DB table spy_api_key.
+ ...
+ ### works for MariaDB and PostgreSQL ###
+ [Arguments] ${key_hash}=${dummy_key_hash}
+ Connect to Spryker DB
+ ${hash_id}= Query select id_api_key from spy_api_key WHERE key_hash='${key_hash}';
+ ${hash_id_length}= Get Length ${hash_id}
+ IF ${hash_id_length} > 0
+ Execute Sql String DELETE FROM spy_api_key WHERE key_hash='${key_hash}';
+ END
+ Disconnect From Database
+
+Delete mime_type by id_mime_type in Database:
+ [Documentation] This keyword deletes a mime type by id_mime_type in the DB table spy_mime_type.
+ ... *Example:*
+ ...
+ ... ``Delete mime_type by id_mime_type in Database: 21``
+ ...
+ [Arguments] ${id_mime_type}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_mime_type WHERE id_mime_type = '${id_mime_type}';
+ Disconnect From Database
+
+Find first available product via data exchange api
+ [Arguments] ${start_from_index}=0 ${end_index}=100
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ I get access token by user credentials: ${zed_admin.email}
+ I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ FOR ${index} IN RANGE ${start_from_index} ${end_index}
+ I send a GET request: /dynamic-entity/stock-products/${index}
+ ${is_200}= Run Keyword And Ignore Error Response status code should be: 200
+ IF 'FAIL' in $is_200 Continue For Loop
+ Save value to a variable: [data][is_never_out_of_stock] initial_is_never_out_of_stock
+ Save value to a variable: [data][quantity] initial_quantity
+ IF '${initial_is_never_out_of_stock}' == 'False'
+ IF ${initial_quantity} > 0
+ Save value to a variable: [data][fk_product] fk_product
+ Set Test Variable ${index} ${index}
+ Exit For Loop
+ ELSE
+ Continue For Loop
+ END
+ ELSE
+ Save value to a variable: [data][fk_product] fk_product
+ Set Test Variable ${index} ${index}
+ Exit For Loop
+ END
+ END
+ Get concrete product sku by id from DB: ${fk_product}
+ Make sure that concrete product is available: ${concrete_sku}
+ RETURN ${concrete_sku}
+
+Make sure that concrete product is available:
+ [Arguments] ${sku}=${concrete_sku}
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type==application/json
+ I send a GET request: /concrete-products/${concrete_sku}/concrete-product-availabilities
+ ${is_available}= Run Keyword And Ignore Error Response body parameter should be: [data][0][attributes][availability] True
+ IF 'FAIL' in $is_available
+ ${index}= Evaluate ${index}+1
+ Find first available product via data exchange api ${index}
+ END
+
+Product availability status should be changed on:
+ [Arguments] ${is_available} ${sku}=${concrete_sku} ${sleep_time}=5s ${iterations}=26
+ ${is_available}= Convert To Title Case ${is_available}
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type==application/json
+ FOR ${index} IN RANGE 1 ${iterations}
+ I send a GET request: /concrete-products/${concrete_sku}/concrete-product-availabilities
+ Response status code should be: 200
+ ${actual_availability}= Run Keyword And Ignore Error Response body parameter should be: [data][0][attributes][availability] ${is_available}
+ IF ${index} == ${iterations}-1
+ Fail Expected product availability is not reached. Check P&S
+ END
+ IF 'PASS' in $actual_availability
+ Exit For Loop
+ END
+ IF 'FAIL' in $actual_availability
+ Sleep ${sleep_time}
+ Continue For Loop
+ END
+
+ END
+
+Restore product initial stock via data exchange api:
+ [Arguments] ${id_stock_product}=${index}
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ I get access token by user credentials: ${zed_admin.email}
+ I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ Log ${initial_is_never_out_of_stock}
+ ${initial_is_never_out_of_stock}= To JSON Boolean ${initial_is_never_out_of_stock}
+ I send a PATCH request: /dynamic-entity/stock-products/${id_stock_product} {"data":{"is_never_out_of_stock":${initial_is_never_out_of_stock},"quantity":${initial_quantity}}}
diff --git a/atest/testdata/performance/resources/steps/api_service_point_steps.robot b/atest/testdata/performance/resources/steps/api_service_point_steps.robot
new file mode 100644
index 0000000..56717a1
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/api_service_point_steps.robot
@@ -0,0 +1,382 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Get id service point by uuid
+ [Documentation] This keyword returns Service Point ID ${servicePointIds[0][0]} by Service Point UUID.
+ ... *Example:*
+ ...
+ ... ``Get id service point by uuid uuid=262feb9d-33a7-5c55-9b04-45b1fd22067e``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ ${servicePointIds} Query SELECT id_service_point FROM spy_service_point WHERE uuid = '${uuid}' ORDER BY id_service_point DESC LIMIT 1;
+ Disconnect From Database
+ RETURN ${servicePointIds[0][0]}
+
+Create service point in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service_point`. If `storeName` is provided, creates store relation.
+ ... *Example:*
+ ...
+ ... ``Create service point in DB uuid=262feb9d-33a7-5c55-9b04-45b1fd22067e name=Main Service Point key=sp1 isActive=true storeName=DE``
+ ...
+ [Arguments] ${uuid}=${None} ${name}=${None} ${key}=${None} ${isActive}=${True} ${storeName}=DE
+ IF '${uuid}' == '${None}'
+ ${uuid}= Evaluate uuid.uuid4()
+ END
+ IF '${name}' == '${None}'
+ ${name}= Generate Random String 5 [LETTERS]
+ END
+ IF '${key}' == '${None}'
+ ${key}= Generate Random String 5 [LETTERS]
+ END
+ ${idServicePoint}= Get next id from table spy_service_point id_service_point
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_service_point (`key`, name, uuid, is_active) value ('${key}', '${name}', '${uuid}', ${isActive});
+ ELSE
+ Execute Sql String INSERT INTO spy_service_point (id_service_point, key, name, uuid, is_active) VALUES (${idServicePoint}, '${key}', '${name}', '${uuid}', ${isActive});
+ END
+ Disconnect From Database
+ IF '${storeName}' != '${None}'
+ Create service point store relation in DB ${uuid} ${storeName}
+ END
+
+Create service point store relation in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service_point_store`.
+ ... *Example:*
+ ...
+ ... ``Create service point store relation in DB servicePointUuid=262feb9d-33a7-5c55-9b04-45b1fd22067e storeName=DE``
+ ...
+ [Arguments] ${servicePointUuid} ${storeName}
+ ${idServicePoint}= Get id service point by uuid ${servicePointUuid}
+ ${idServicePointStore}= Get next id from table spy_service_point_store id_service_point_store
+ Connect to Spryker DB
+ ${storeIds}= Query SELECT id_store FROM spy_store WHERE name = '${storeName}' ORDER BY id_store DESC LIMIT 1;
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_service_point_store (fk_service_point, fk_store) value (${idServicePoint}, ${storeIds[0][0]});
+ ELSE
+ Execute Sql String INSERT INTO spy_service_point_store (id_service_point_store, fk_service_point, fk_store) VALUES (${idServicePointStore}, ${idServicePoint}, ${storeIds[0][0]});
+ END
+ Disconnect From Database
+
+Create service point address in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service_point_address`.
+ ... *Example:*
+ ...
+ ... ``Create service point address in DB servicePointUuid=262feb9d-33a7-5c55-9b04-45b1fd22067e uuid=262feb9d-33a7-5c55 address1=Main address2=8 city=Berlin zipCode=10115 countryIso2Code=DE``
+ ...
+ [Arguments] ${servicePointUuid} ${uuid}=${None} ${address1}=${None} ${address2}=${None} ${address3}=${None} ${city}=${None} ${zipCode}=${None} ${countryIso2Code}=DE
+ ${idServicePoint}= Get id service point by uuid ${servicePointUuid}
+ IF '${uuid}' == '${None}'
+ ${uuid}= Evaluate uuid.uuid4()
+ END
+ IF '${address1}' == '${None}'
+ ${address1}= Generate Random String 5 [LETTERS]
+ END
+ IF '${address2}' == '${None}'
+ ${address2}= Generate Random String 5 [LETTERS]
+ END
+ IF '${address3}' == '${None}'
+ ${address3}= Generate Random String 5 [LETTERS]
+ END
+ IF '${city}' == '${None}'
+ ${city}= Generate Random String 5 [LETTERS]
+ END
+ IF '${zipCode}' == '${None}'
+ ${zipCode}= Generate Random String 5 [NUMBERS]
+ END
+ ${idServicePointAddress}= Get next id from table spy_service_point_address id_service_point_address
+ Connect to Spryker DB
+ ${countryIds}= Query SELECT id_country FROM spy_country WHERE iso2_code = '${countryIso2Code}' ORDER BY id_country DESC LIMIT 1;
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_service_point_address (fk_service_point, fk_country, uuid, address1, address2, address3, city, zip_code) value (${idServicePoint}, ${countryIds[0][0]}, '${uuid}', '${address1}', '${address2}', '${address3}', '${city}', '${zipCode}');
+ ELSE
+ Execute Sql String INSERT INTO spy_service_point_address (id_service_point_address, fk_service_point, fk_country, uuid, address1, address2, address3, city, zip_code) VALUES (${idServicePointAddress}, ${idServicePoint}, ${countryIds[0][0]}, '${uuid}', '${address1}', '${address2}', '${address3}', '${city}', '${zipCode}');
+ END
+ Disconnect From Database
+
+Create service point with address and store relations in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service_point` with address and store relations.
+ ... *Example:*
+ ...
+ ... ``Create service point with address and store relations in DB servicePointUuid=262feb9d-33a7-5c55-9b04-45b1fd22067e servicePointAddressUuid=262feb9d-33a7-5c55 storeName=DE``
+ ...
+ [Arguments] ${servicePointUuid} ${servicePointAddressUuid}=${None} ${storeName}=DE
+ Create service point in DB uuid=${servicePointUuid} storeName=${storeName}
+ Create service point address in DB servicePointUuid=${servicePointUuid} uuid=${servicePointAddressUuid}
+
+Create service in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service`.
+ ... *Example:*
+ ...
+ ... ``Create service in DB servicePointUuid=262feb9d-33a7-5c55-9b04-45b1fd22067e serviceTypeUuid=33a7-5c55-9b04 uuid=262feb1fd22067e key=s1 isActive=true``
+ ...
+ [Arguments] ${servicePointUuid} ${serviceTypeUuid} ${uuid}=${None} ${key}=${None} ${isActive}=${True}
+ IF '${uuid}' == '${None}'
+ ${uuid}= Evaluate uuid.uuid4()
+ END
+ IF '${key}' == '${None}'
+ ${key}= Generate Random String 5 [LETTERS]
+ END
+ ${idServicePoint}= Get id service point by uuid ${servicePointUuid}
+ ${idService}= Get next id from table spy_service id_service
+ Connect to Spryker DB
+ ${serviceTypeIds}= Query SELECT id_service_type FROM spy_service_type WHERE uuid = '${serviceTypeUuid}' ORDER BY id_service_type DESC LIMIT 1;
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_service (fk_service_point, fk_service_type, `key`, uuid, is_active) value (${idServicePoint}, ${serviceTypeIds[0][0]}, '${key}', '${uuid}', ${isActive});
+ ELSE
+ Execute Sql String INSERT INTO spy_service (id_service, fk_service_point, fk_service_type, key, uuid, is_active) VALUES (${idService}, ${idServicePoint}, ${serviceTypeIds[0][0]}, '${key}', '${uuid}', ${isActive});
+ END
+ Disconnect From Database
+
+Create service type in DB
+ [Documentation] This keyword creates a new entry in the DB table `spy_service_type`.
+ ... *Example:*
+ ...
+ ... ``Create service type in DB uuid=33a7-5c55-9b04 name=Main Service Point key=sp1``
+ ...
+ [Arguments] ${uuid}=${None} ${name}=${None} ${key}=${None}
+ IF '${uuid}' == '${None}'
+ ${uuid}= Evaluate uuid.uuid4()
+ END
+ IF '${name}' == '${None}'
+ ${name}= Generate Random String 5 [LETTERS]
+ END
+ IF '${key}' == '${None}'
+ ${key}= Generate Random String 5 [LETTERS]
+ END
+ ${idServiceType}= Get next id from table spy_service_type id_service_type
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_service_type (`key`, name, uuid) value ('${key}', '${name}', '${uuid}');
+ ELSE
+ Execute Sql String INSERT INTO spy_service_type (id_service_type, key, name, uuid) VALUES (${idServiceType}, '${key}', '${name}', '${uuid}');
+ END
+ Disconnect From Database
+
+Create region in DB:
+ [Documentation] This keyword creates a new entry in the DB table `spy_region`.
+ ... *Example:*
+ ...
+ ... ``Create region in DB: country=60 iso2_code=DE name=Germany``
+ ...
+ [Arguments] ${country} ${iso2_code} ${name}=${None} ${uuid}=${None}
+ IF '${name}' == '${None}'
+ ${name}= Generate Random String 5 [LETTERS]
+ END
+ IF '${uuid}' == '${None}'
+ ${uuid}= Generate Random String 5 [LETTERS]
+ END
+ ${new_id}= Get next id from table spy_region id_region
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_region (fk_country, iso2_code, name, uuid) value ('${country}', '${iso2_code}', '${name}','${uuid}');
+ ELSE
+ Execute Sql String INSERT INTO spy_region (id_region, fk_country, iso2_code, name, uuid) VALUES (${new_id}, '${country}', '${iso2_code}', '${name}','${uuid}');
+ END
+ Disconnect From Database
+
+Get service point uuid by key:
+ [Documentation] This keyword returns Service Point UUID ${servicePointUuid} by Service Point KEY.
+ ... *Example:*
+ ...
+ ... ``Get service point uuid by key: some-service-point-34395``
+ ...
+ [Arguments] ${key}
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ ${servicePointUuid} Query SELECT uuid FROM spy_service_point WHERE `key` = '${key}' ORDER BY uuid DESC LIMIT 1;
+ ELSE
+ ${servicePointUuid} Query SELECT uuid FROM spy_service_point WHERE "key" = '${key}' ORDER BY uuid DESC LIMIT 1;
+ END
+ Disconnect From Database
+ Set Test Variable ${servicePointUuid} ${servicePointUuid[0][0]}
+ RETURN ${servicePointUuid}
+
+Delete service point in DB
+ [Documentation] This keyword deletes the entry from the DB table `spy_service_point`. If `withRelations=true`, deletes with relations.
+ ... *Example:*
+ ...
+ ... ``Get service point uuid by key: ${service_point_key}``
+ ... `` Delete service point in DB ${servicePointUuid}``
+ ... OR
+ ... ``Delete service point in DB uuid=262feb9d-33a7-5c55-9b04-45b1fd22067e withRelations=true``
+ ...
+ [Arguments] ${uuid} ${withRelations}=${True}
+ Deactivate service points in DB ${uuid}
+ IF ${withRelations}
+ ${idServicePoint}= Get id service point by uuid ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_service_point_store WHERE fk_service_point = ${idServicePoint};
+ Execute Sql String DELETE FROM spy_service_point_address WHERE fk_service_point = ${idServicePoint};
+ Execute Sql String DELETE FROM spy_service WHERE fk_service_point = ${idServicePoint};
+ Disconnect From Database
+ END
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_service_point WHERE uuid = '${uuid}';
+ Disconnect From Database
+
+Delete service point address in DB
+ [Documentation] This keyword deletes the entry from the DB table `spy_service_point_address`.
+ ... *Example:*
+ ...
+ ... ``Delete service point address in DB uuid=262feb9d-33a7-5c55-9b04-45b1fd22067e``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_service_point_address WHERE uuid = '${uuid}';
+ Disconnect From Database
+
+Delete service type in DB
+ [Documentation] This keyword deletes the entry from the DB table `spy_service_type`.
+ ... *Example:*
+ ...
+ ... ``Delete service type in DB uuid=33a7-5c55-9b04``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_service_type WHERE uuid = '${uuid}';
+ Disconnect From Database
+
+Deactivate service points in DB
+ [Documentation] This keyword deactivates service points. If `uuid` is provided, deactivates service point by uuid.
+ ... *Example:*
+ ...
+ ... ``Deactivate service point in DB uuid=262feb9d-33a7-5c55-9b04-45b1fd22067e``
+ ...
+ [Arguments] ${uuid}=${None}
+ ${query} Set Variable UPDATE spy_service_point SET is_active = false
+ IF '${uuid}' != '${None}'
+ ${query} Set Variable ${query} WHERE uuid = '${uuid}'
+ END
+ Log ${query}
+ Connect to Spryker DB
+ Execute Sql String ${query};
+ Disconnect From Database
+
+Deactivate service point via BAPI
+ [Arguments] ${service_point_uuid}
+ ${have_access_token} Run Keyword and return status Should Contain ${headers} Authorization
+ IF not ${have_access_token}
+ I get access token by user credentials: ${zed_admin.email}
+ I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ END
+ I send a PATCH request: /service-points/${service_point_uuid} {"data": {"type": "service-points","attributes": {"isActive": "false"}}}
+ Response status code should be: 200
+
+Deactivate service via BAPI
+ [Arguments] ${service_uuid}
+ ${have_access_token} Run Keyword and return status Should Contain ${headers} Authorization
+ IF not ${have_access_token}
+ I get access token by user credentials: ${zed_admin.email}
+ I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ END
+ I send a PATCH request: When I send a PATCH request: /services/${service_uuid} {"data": {"type": "services", "attributes": {"isActive": "false"}}}
+ Response status code should be: 200
+
+Create dynamic service with all data via BAPI if doesn't exist
+ Connect to Spryker DB
+ # Check if 'robot' dynamic service point already exists
+ IF '${db_engine}' == 'pymysql'
+ ${dynamic_service_point_uuid}= Query SELECT uuid FROM spy_service_point WHERE `key` LIKE '%${dynamic_service.service_point_key}%' ORDER BY id_service_point DESC LIMIT 1;
+ ELSE
+ ${dynamic_service_point_uuid}= Query SELECT uuid FROM spy_service_point WHERE "key" ILIKE '%${dynamic_service.service_point_key}%' ORDER BY id_service_point DESC LIMIT 1;
+ END
+ ${dynamic_service_point_exists}= Evaluate len(${dynamic_service_point_uuid}) > 0
+ VAR ${dynamic_service_point_exists} ${dynamic_service_point_exists} scope=SUITE
+
+ IF ${dynamic_service_point_exists}
+ VAR ${dynamic_service_point_uuid} ${dynamic_service_point_uuid}[0][0] scope=SUITE
+ IF '${db_engine}' == 'pymysql'
+ ${dynamic_service_point_address_uuid}= Query SELECT uuid FROM spy_service_point_address WHERE city LIKE '%${dynamic_service.service_point_address_city}%' ORDER BY id_service_point_address DESC LIMIT 1;
+ VAR ${dynamic_service_point_address_uuid} ${dynamic_service_point_address_uuid}[0][0] scope=SUITE
+
+ ${dynamic_service_type_uuid}= Query SELECT uuid FROM spy_service_type WHERE `key` LIKE '%${dynamic_service.service_type_key}%' ORDER BY id_service_type DESC LIMIT 1;
+ VAR ${dynamic_service_type_uuid} ${dynamic_service_type_uuid}[0][0] scope=SUITE
+
+ ${dynamic_service_uuid}= Query SELECT uuid FROM spy_service WHERE `key` LIKE '%${dynamic_service.service_key}%' ORDER BY id_service DESC LIMIT 1;
+ VAR ${dynamic_service_uuid} ${dynamic_service_uuid}[0][0] scope=SUITE
+ ELSE
+ ${dynamic_service_point_address_uuid}= Query SELECT uuid FROM spy_service_point_address WHERE city ILIKE '%${dynamic_service.service_point_address_city}%' ORDER BY id_service_point_address DESC LIMIT 1;
+ VAR ${dynamic_service_point_address_uuid} ${dynamic_service_point_address_uuid}[0][0] scope=SUITE
+
+ ${dynamic_service_type_uuid}= Query SELECT uuid FROM spy_service_type WHERE "key" ILIKE '%${dynamic_service.service_type_key}%' ORDER BY id_service_type DESC LIMIT 1;
+ VAR ${dynamic_service_type_uuid} ${dynamic_service_type_uuid}[0][0] scope=SUITE
+
+ ${dynamic_service_uuid}= Query SELECT uuid FROM spy_service WHERE "key" ILIKE '%${dynamic_service.service_key}%' ORDER BY id_service DESC LIMIT 1;
+ VAR ${dynamic_service_uuid} ${dynamic_service_uuid}[0][0] scope=SUITE
+ END
+ END
+
+ Disconnect From Database
+
+ IF not ${dynamic_service_point_exists}
+ # Create Service Point
+ Switch to BAPI
+ I get access token by user credentials: ${zed_admin.email}
+ I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "${dynamic_service.service_point_name}","key": "${dynamic_service.service_point_key}","isActive": "true","stores": ["DE"]}}}
+ Response status code should be: 201
+ Save value to a variable: [data][id] service_point_id
+
+ VAR ${dynamic_service_point_uuid} ${service_point_id} scope=SUITE
+
+ # Create Service Point Address
+ I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"${dynamic_service.service_point_address_line_1}","address2":"${dynamic_service.service_point_address_line_2}","city":"${dynamic_service.service_point_address_city}","zipCode":"${dynamic_service.service_point_address_zip_code}","countryIso2Code":"${dynamic_service.service_point_address_country}"}}}
+ Response status code should be: 201
+ Save value to a variable: [data][id] service_point_address_id
+
+ VAR ${dynamic_service_point_address_uuid} ${service_point_address_id} scope=SUITE
+
+ # Create Service Type
+ I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "${dynamic_service.service_type_name}", "key": "${dynamic_service.service_type_key}"}}}
+ Response status code should be: 201
+ Save value to a variable: [data][id] service_type_id
+
+ VAR ${dynamic_service_type_uuid} ${service_type_id} scope=SUITE
+
+ # Create Service
+ I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "${dynamic_service.service_key}"}}}
+ Response status code should be: 201
+ Save value to a variable: [data][id] service_id
+
+ VAR ${dynamic_service_uuid} ${service_id} scope=SUITE
+
+ # Publish to Redis and ES
+ Repeat Keyword 3 Trigger p&s
+ END
+
+Delete all non-default service points from DB with p&s
+ [Documentation] This keyword deletes all non-default service points from the `spy_service_point` table.
+ ... It also deletes related entries from `spy_service_point_store`, `spy_service_point_address`, and `spy_service`.
+ ... It processes all service points where `id_service_point > 3`.
+ ...
+ [Tags] Database Cleanup
+
+ Connect to Spryker DB
+ ${service_point_uuids}= Query SELECT uuid FROM spy_service_point WHERE id_service_point > 2;
+
+ FOR ${row} IN @{service_point_uuids}
+ ${uuid}= Set Variable ${row}[0]
+ ${idServicePoint}= Get id service point by uuid ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_service_point_store WHERE fk_service_point = ${idServicePoint};
+ Execute Sql String DELETE FROM spy_service_point_address WHERE fk_service_point = ${idServicePoint};
+ Execute Sql String DELETE FROM spy_product_offer_service WHERE fk_service IN (SELECT id_service FROM spy_service WHERE fk_service_point = ${idServicePoint});
+ Execute Sql String DELETE FROM spy_service WHERE fk_service_point = ${idServicePoint};
+ Execute Sql String DELETE FROM spy_service_point WHERE uuid = '${uuid}';
+ END
+
+ ${service_types_uuids}= Query SELECT uuid FROM spy_service_type WHERE id_service_type > 2;
+ FOR ${row} IN @{service_types_uuids}
+ ${uuid}= Set Variable ${row}[0]
+ Execute Sql String DELETE FROM spy_shipment_type_service_type WHERE fk_service_type > 2;
+ Execute Sql String DELETE FROM spy_service_type WHERE uuid = '${uuid}';
+ END
+
+ Disconnect From Database
+ Trigger publish trigger-events service_point timeout=1s
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/availability_steps.robot b/atest/testdata/performance/resources/steps/availability_steps.robot
new file mode 100644
index 0000000..682b9e7
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/availability_steps.robot
@@ -0,0 +1,33 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../../resources/pages/zed/zed_edit_warehouse_page.robot
+Resource products_steps.robot
+
+*** Keywords ***
+Zed: update warehouse:
+ [Arguments] @{args}
+ ${warehouseData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /stock-gui/warehouse/list
+ Zed: click Action Button in a table for row that contains: ${warehouse} Edit
+ Wait Until Element Is Visible ${zed_warehouse_name}
+ FOR ${key} ${value} IN &{warehouseData}
+ IF '${key}'=='name' and '${value}' != '${EMPTY}' Type Text ${zed_warehouse_name} ${value}
+ IF '${key}'=='available' and '${value}' != '${EMPTY}' Click xpath=//label[contains(text(),'${value}')]
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Store Relation']
+ Zed: Check checkbox by Label: ${value}
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Configuration']
+ END
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}'
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Store Relation']
+ Zed: Check checkbox by Label: ${value}
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Configuration']
+ END
+ IF '${key}'=='unselect store' and '${value}' != '${EMPTY}'
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Store Relation']
+ Zed: Uncheck Checkbox by Label: ${value}
+ Click xpath=//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='Configuration']
+ END
+ END
+ Zed: submit the form
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/catalog_steps.robot b/atest/testdata/performance/resources/steps/catalog_steps.robot
new file mode 100644
index 0000000..1756ff3
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/catalog_steps.robot
@@ -0,0 +1,235 @@
+*** Settings ***
+Resource ../pages/yves/yves_catalog_page.robot
+Resource ../common/common_yves.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Yves: 'Catalog' page should show products:
+ [Arguments] ${productsCount}
+ Wait Until Element Is Visible ${catalog_products_counter_locator}[${env}]
+ Element Should Contain ${catalog_products_counter_locator}[${env}] ${productsCount}
+
+Yves: product with name in the catalog should have price:
+ [Arguments] ${productName} ${expectedProductPrice}
+ IF '${env}' in ['ui_suite']
+ ${actualProductPrice}= Get Text xpath=(//product-item[@data-qa='component product-item'])[1]//a[contains(@class,'name')][contains(.,'${productName}')]/ancestor::product-item//*[@itemprop='price'][contains(@class,'default-price')]
+ ELSE
+ ${actualProductPrice}= Get Text xpath=//product-item[@data-qa='component product-item']//*[contains(@class,'product-item__name')][contains(text(),'${productName}')]/ancestor::product-item//*[@data-qa='component money-price']/*[contains(@class,'money-price__amount')][contains(@class,'default')]
+ END
+ ${actualProductPrice}= Remove String ${actualProductPrice} ${SPACE}
+ Should Be Equal ${actualProductPrice} ${expectedProductPrice} message=Actual product price is '${actualProductPrice}' but expected to have '${expectedProductPrice}'
+
+Yves: page contains CMS element:
+ [Documentation] Arguments are ${type} ${title}, ${type} can be: CMS Block, Banner, Product Slider, Homepage Banners, Homepage Inspirational Block, Homepage Banner Video, Footer section, CMS Page Title, CMS Page Content
+ [Arguments] ${type} ${text}=
+ IF '${type}'=='banner'
+ Element Should Be Visible xpath=//*[contains(@class,'headline--category') and contains(text(),'${text}')]
+ ELSE IF '${type}'=='Product slider'
+ Element Should Be Visible xpath=//*[contains(@class,'catalog-cms-block')]//*[contains(@class,'title') and contains(text(),'${text}')]
+ ELSE IF '${type}'=='Homepage Banners'
+ Element Should Be Visible xpath=//div[contains(@class,'slick-carousel__container js-slick-carousel__container slick-initialized slick-slider slick-dotted')]
+ ELSE IF '${type}'=='Homepage Inspirational Block'
+ Element Should Be Visible xpath=//*[contains(@class,'multi-inspirational-block__title')]
+ ELSE IF '${type}'=='Homepage Banner Video'
+ Element Should Be Visible xpath=//*[contains(@class,'image-banner__video')]
+ ELSE IF '${type}'=='Footer section'
+ Element Should Be Visible xpath=//*[@class='footer']
+ ELSE IF '${type}'=='CMS Page Title'
+ IF '${env}' in ['ui_suite']
+ Element Should Be Visible xpath=//*[contains(@data-qa,'breadcrumb')]/ancestor::div[1]//p[contains(.,'${text}')]
+ ELSE
+ Element Should Be Visible xpath=//*[contains(@class,'cms-page')][contains(@class,'title')]//*[contains(text(),'${text}')]
+ END
+ ELSE IF '${type}'=='CMS Page Content' and '${env}' in ['ui_b2c','ui_mp_b2c']
+ Element Should Be Visible xpath=//*[contains(@class,'cms-page__content')]//*[contains(text(),'${text}')]
+ ELSE IF '${type}'=='CMS Page Content' and '${env}' in ['ui_b2b','ui_mp_b2b']
+ Element Should Be Visible xpath=//main[contains(@class,'cms-page')]//*[contains(text(),'${text}')]
+ ELSE IF '${type}'=='CMS Page Content' and '${env}' in ['ui_suite']
+ Element Should Be Visible xpath=//main//p[contains(.,'${text}')]
+ ELSE IF '${type}'=='CMS Block'
+ Element Should Be Visible xpath=//div[contains(@class,'catalog-cms-block')]//*[.="${text}"]
+ END
+
+Yves: change sorting order on catalog page:
+ [Arguments] ${sortingOption}
+ IF '${env}' in ['ui_suite']
+ Select From List By Label ${catalog_sorting_selector} ${sortingOption}
+ Click ${catalog_apply_sorting_button}
+ ELSE
+ Click xpath=//span[contains(@id,'select2-sort')]
+ Wait Until Element Is Visible xpath=//ul[contains(@role,'listbox')]//li[contains(@id,'select2-sort') and contains(text(),'${sortingOption}')]
+ Click xpath=//ul[contains(@role,'listbox')]//li[contains(@id,'select2-sort') and contains(text(),'${sortingOption}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: 1st product card in catalog (not)contains:
+ [Documentation] ${elementName} can be: Price, Name, Add to Cart, Color selector, Sale label, New label
+ [Arguments] ${elementName} ${value}
+ ${value}= Convert To Lower Case ${value}
+ IF '${elementName}'=='Price' and '${value}'=='true'
+ Element Should Be Visible xpath=//product-item[@data-qa='component product-item'][1]//span[contains(@class,'default-price') and contains(.,'${value}')]
+ ELSE IF '${elementName}'=='Price' and '${value}'=='false'
+ Element Should Not Be Visible xpath=//product-item[@data-qa='component product-item'][1]//span[contains(@class,'default-price') and contains(.,'${value}')]
+ ELSE IF '${elementName}'=='Original Price' and '${value}'=='false'
+ Element Should Not Be Visible xpath=//product-item[@data-qa='component product-item'][1]//span[contains(@class,'original-price') and contains(.,'${value}')]
+ ELSE IF '${elementName}'=='Name' and '${value}'=='true'
+ Element Should Be Visible xpath=//product-item[@data-qa='component product-item'][1]//*[contains(@class,'item__name') and contains(.,'${value}')]
+ ELSE IF '${elementName}'=='Name' and '${value}'=='false'
+ Element Should Not Be Visible xpath=//product-item[@data-qa='component product-item'][1]//*[contains(@class,'item__name') and contains(.,'${value}')]
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b','ui_suite'] and '${elementName}'=='Add to Cart' and '${value}'=='true'
+ Page Should Not Contain Element xpath=(//product-item[@data-qa='component product-item'])[1]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled='']
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b','ui_suite'] and '${elementName}'=='Add to Cart' and '${value}'=='false'
+ Page Should Contain Element xpath=(//product-item[@data-qa='component product-item'])[1]//*[@class='product-item__actions']//ajax-add-to-cart//button[@disabled='']
+ ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c'] and '${elementName}'=='Add to Cart' and '${value}'=='true'
+ Element Should Be Visible xpath=//product-item[@data-qa='component product-item'][1]//ajax-add-to-cart//button
+ ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c'] and '${elementName}'=='Add to Cart' and '${value}'=='false'
+ Element Should Not Be Visible xpath=//product-item[@data-qa='component product-item'][1]//ajax-add-to-cart//button
+ ELSE IF '${elementName}'=='Color selector' and '${value}'=='true'
+ Page Should Contain Element xpath=//product-item[@data-qa='component product-item'][1]//product-item-color-selector
+ ELSE IF '${elementName}'=='Color selector' and '${value}'=='false'
+ Page Should Not Contain Element xpath=//product-item[@data-qa='component product-item'][1]//product-item-color-selector
+ ELSE IF '${elementName}'=='Sale label' and '${value}'=='true'
+ Page Should Contain Element xpath=(//product-item[@data-qa='component product-item'][1]//label-group//span[contains(text(),'SALE')])[1]
+ ELSE IF '${elementName}'=='Sale label' and '${value}'=='false'
+ Page Should Not Contain Element xpath=(//product-item[@data-qa='component product-item'][1]//label-group//span[contains(text(),'SALE')])[1]
+ ELSE IF '${elementName}'=='New label' and '${value}'=='true'
+ Page Should Contain Element xpath=(//product-item[@data-qa='component product-item'][1]//label-group//span[contains(text(),'New')])[1]
+ ELSE IF '${elementName}'=='New label' and '${value}'=='false'
+ Page Should Not Contain Element xpath=(//product-item[@data-qa='component product-item'][1]//label-group//span[contains(text(),'New')])[1]
+ END
+
+Yves: go to catalog page:
+ [Arguments] ${pageNumber}
+ Click xpath=(//a[contains(@class,'pagination__step') and contains(text(),'${pageNumber}')])[1]
+
+Yves: catalog page contains filter:
+ [Arguments] @{listOfFilters}
+ FOR ${filter} IN @{listOfFilters}
+ Log Looking for filter: ${filter}
+ IF '${env}' in ['ui_suite']
+ Element Should Be Visible xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'title')][contains(.,'${filter}')]
+ ELSE
+ Element Should Be Visible xpath=//*[contains(@class,'filter') and contains(text(),'${filter}')]
+ END
+ END
+
+Yves: select filter value:
+ [Arguments] ${filter} ${filterValue}
+ IF '${env}' in ['ui_suite']
+ Check Checkbox xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'title')][contains(.,'${filter}')]/..//input[@value='${filterValue}'] force=true
+ Click ${catalog_filter_apply_button}
+ ELSE
+ Wait Until Element Is Visible xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]
+ Click xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]
+ Disable Automatic Screenshots on Failure
+ ${filter_expanded}= Run Keyword And Ignore Error Wait Until Element Is Visible xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]/following-sibling::*//span[contains(@data-qa,'checkbox')][contains(.,'${filterValue}')] timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $filter_expanded
+ Reload
+ Wait Until Element Is Visible xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]
+ Click xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]
+ END
+ Click xpath=//section[contains(@data-qa,'component filter-section')]//*[contains(@class,'filter-section')][contains(text(),'${filter}')]/following-sibling::*//span[contains(@data-qa,'checkbox')][contains(.,'${filterValue}')]
+ Click ${catalog_filter_apply_button}
+ END
+
+Yves: quick add to cart for first item in catalog
+ IF '${env}' in ['ui_b2b','ui_mp_b2b','ui_suite']
+ Click xpath=(//product-item[@data-qa='component product-item'][1]//*[@class='product-item__actions']//ajax-add-to-cart//button)[1]
+ ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Scroll Element Into View xpath=//product-item[@data-qa='component product-item'][1]//div[contains(@class,'image-wrap')]
+ Mouse Over xpath=//product-item[@data-qa='component product-item'][1]//div[contains(@class,'image-wrap')]
+ Wait Until Element Is Visible xpath=//product-item[@data-qa='component product-item'][1]//ajax-add-to-cart//button
+ Click xpath=//product-item[@data-qa='component product-item'][1]//ajax-add-to-cart//button
+ END
+ Wait For Response
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: get current cart item counter value
+ [Documentation] returns the cart item count number as an integer
+ ${currentCartCounterText}= Evaluate Javascript ${None} document.evaluate("//*[@data-qa='component navigation-top']//span[contains(@class,'cart-counter__quantity js-cart-counter__quantity')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.textContent
+ ${currentCartCounter}= Convert To Integer ${currentCartCounterText}
+ RETURN ${currentCartCounter}
+
+Yves: mouse over color on product card:
+ [Documentation] the color should start with capital letter, e.g. Black, Red, White
+ [Arguments] ${colour}
+ IF '${env}' in ['ui_suite']
+ Click xpath=(//product-item[@data-qa='component product-item'])[1]//product-item-color-selector//button[contains(@style,'${colour}')]
+ ELSE
+ Mouse Over xpath=//product-item[@data-qa='component product-item'][1]//*[contains(@class,'item__name')]
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible xpath=//product-item[@data-qa='component product-item'][1]//product-item-color-selector
+ Mouse Over xpath=//product-item[@data-qa='component product-item'][1]//product-item-color-selector//span[contains(@class,'tooltip')][contains(text(),'${colour}')]/ancestor::button
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: at least one product is/not displayed on the search results page:
+ [Arguments] ${search_query} ${expected_visibility} ${wait_for_p&s}=${False} ${iterations}=26 ${delay}=3s
+ Yves: perform search by: ${search_query}
+ ${expected_visibility}= Convert To Lower Case ${expected_visibility}
+ IF '${expected_visibility}' == 'true'
+ ${expected_visibility}= Set Variable ${True}
+ END
+ IF '${expected_visibility}' == 'yes'
+ ${expected_visibility}= Set Variable ${True}
+ END
+ IF '${expected_visibility}' == 'displayed'
+ ${expected_visibility}= Set Variable ${True}
+ END
+ IF '${expected_visibility}' == 'is displayed'
+ ${expected_visibility}= Set Variable ${True}
+ END
+ IF '${expected_visibility}' == 'false'
+ ${expected_visibility}= Set Variable ${False}
+ END
+ ${wait_for_p&s}= Convert To String ${wait_for_p&s}
+ ${wait_for_p&s}= Convert To Lower Case ${wait_for_p&s}
+ IF '${wait_for_p&s}' == 'true'
+ ${wait_for_p&s}= Set Variable ${True}
+ END
+ IF '${wait_for_p&s}' == 'false'
+ ${wait_for_p&s}= Set Variable ${False}
+ END
+ IF ${wait_for_p&s}
+ FOR ${index} IN RANGE 1 ${iterations}
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected product visibility is not reached
+ END
+ IF ${expected_visibility}
+ ${result}= Run Keyword And Ignore Error Page Should Contain Element ${catalog_product_card_locator}
+ ELSE
+ ${result}= Run Keyword And Ignore Error Page Should Not Contain Element ${catalog_product_card_locator}
+ END
+ IF 'FAIL' in $result
+ Sleep ${delay}
+ Reload
+ Continue For Loop
+ ELSE
+ Exit For Loop
+ END
+ END
+ ELSE
+ IF ${expected_visibility}
+ Page Should Contain Element ${catalog_product_card_locator}
+ ELSE
+ Page Should Not Contain Element ${catalog_product_card_locator}
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/change_password_steps.robot b/atest/testdata/performance/resources/steps/change_password_steps.robot
new file mode 100644
index 0000000..acc75ba
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/change_password_steps.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Resource ../common/common_ui.robot
+
+*** Keywords ***
+Yves: set new password on Restore Password page
+ wait until element is visible ${new_password_field}
+ Type Text ${new_password_field} ${default_password}
+ Type Text ${confirm_new_password_field} ${default_password}
+ Click ${new_password_submit_button}
+ Wait Until Page Does Not Contain Element ${new_password_submit_button}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/checkout_steps.robot b/atest/testdata/performance/resources/steps/checkout_steps.robot
new file mode 100644
index 0000000..f1c764c
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/checkout_steps.robot
@@ -0,0 +1,821 @@
+*** Settings ***
+Resource ../pages/yves/yves_checkout_address_page.robot
+Resource ../pages/yves/yves_checkout_login_page.robot
+Resource ../pages/yves/yves_checkout_payment_page.robot
+Resource ../pages/yves/yves_checkout_summary_page.robot
+Resource ../common/common_yves.robot
+Resource ../common/common.robot
+
+*** Variables ***
+${cancelRequestButton} ${checkout_summary_cancel_request_button}
+${alertWarning} ${checkout_summary_alert_warning}
+${quoteStatus} ${checkout_summary_quote_status}
+${selected address}
+
+*** Keywords ***
+Yves: billing address same as shipping address:
+ [Arguments] ${state}
+ ${state}= Convert To Lower Case ${state}
+ Wait Until Page Contains Element xpath=//form[@name='addressesForm']
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b'] Wait Until Page Contains Element ${manage_your_addresses_link}
+ ${checkboxState}= Set Variable ${EMPTY}
+ ${checkboxState}= Run Keyword And Return Status Page Should Contain Element xpath=//input[@id='addressesForm_billingSameAsShipping'][@checked] timeout=100ms
+ IF '${checkboxState}'=='False' and '${state}' == 'true'
+ Click Element by xpath with JavaScript //input[@id='addressesForm_billingSameAsShipping']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${checkboxState}'=='True' and '${state}' == 'false'
+ Click Element by xpath with JavaScript //input[@id='addressesForm_billingSameAsShipping']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ Sleep 1s
+ IF '${state}' == 'true' Wait Until Element Is Not Visible ${checkout_billing_address_first_name_field}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: 'billing same as shipping' checkbox should be displayed:
+ [Arguments] ${expected_condition}
+ ${expected_condition}= Convert To Lower Case ${expected_condition}
+ IF '${expected_condition}' == 'true'
+ Element Should Be Visible ${checkout_address_billing_same_as_shipping_checkbox} message='billing same as shipping' checkbox is not displayed
+ ELSE
+ Element Should Not Be Visible ${checkout_address_billing_same_as_shipping_checkbox} message='billing same as shipping' checkbox is displayed but should NOT
+ END
+
+Yves: accept the terms and conditions:
+ [Documentation] ${state} can be true or false
+ [Arguments] ${state} ${isGuest}=false
+ ${state}= Convert To Lower Case ${state}
+ ${is_invoice_dob_present}= Run Keyword And Return Status Element Should Not Be Visible ${checkout_payment_invoice_date_of_birth_field}
+ ${is_marketplace_invoice_dob_present}= Run Keyword And Return Status Element Should Not Be Visible ${checkout_payment_marketplace_invoice_date_field}
+ IF not ${is_invoice_dob_present} or not ${is_marketplace_invoice_dob_present}
+ IF not ${is_invoice_dob_present} Type Text ${checkout_payment_invoice_date_of_birth_field} 11.11.2000
+ IF not ${is_marketplace_invoice_dob_present} Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ END
+ IF '${state}' == 'true' and '${isGuest}'=='false'
+ Run keywords
+ Wait Until Page Contains Element xpath=//input[@name='acceptTermsAndConditions']
+ Run Keyword And Ignore Error Click Element by xpath with JavaScript //input[@name='acceptTermsAndConditions']
+ ELSE IF '${state}'=='true' and '${isGuest}'=='true'
+ Run keywords
+ Wait Until Page Contains Element id=guestForm_customer_accept_terms
+ Click Element by id with JavaScript guestForm_customer_accept_terms
+ END
+
+Yves: select the following existing address on the checkout as 'shipping' address and go next:
+ [Arguments] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${is_ssp}' == 'true'
+ Wait Until Element Is Visible ${checkout_address_delivery_selector}[ssp_b2b]
+ ELSE
+ Wait Until Element Is Visible ${checkout_address_delivery_selector}[${env}]
+ END
+ WHILE '${selected_address}' != '${addressToUse}' limit=5
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 200ms
+ ${selected_address}= Get Text xpath=//select[contains(@name,'shippingAddress')][contains(@id,'addressesForm_shippingAddress_id')]/..//span[contains(@id,'shippingAddress_id')]
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ IF '${is_ssp}' == 'true'
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[ssp_b2b] ${addressToUse}
+ ELSE
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 200ms
+ IF '${is_ssp}' == 'true'
+ ${selected_address}= Get Text xpath=(//address-item-form-field-list//select[@name='checkout-full-addresses' and not(ancestor::div[1][contains(@class, 'is-hidden')])]/..//span[contains(@id,'checkout-full-addresses')])[1]
+ ELSE
+ ${selected_address}= Get Text xpath=//div[contains(@class,'shippingAddress')]//select[@name='checkout-full-addresses'][contains(@class,'address__form')]/..//span[contains(@id,'checkout-full-address')]
+ END
+ ELSE
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 200ms
+ Exit For Loop
+ END
+ END
+ IF '${is_ssp}' == 'true'
+ ${ssp_checkout_delivery_address_dropdowns_count}= Get Element Count xpath=//address-item-form-field-list//select[@name='checkout-full-addresses' and not(ancestor::div[1][contains(@class, 'is-hidden')])]
+ IF ${ssp_checkout_delivery_address_dropdowns_count} > 1
+ FOR ${index} IN RANGE 1 ${ssp_checkout_delivery_address_dropdowns_count}
+ Repeat Keyword 2 Select From List By Label xpath=(//address-item-form-field-list//select[@name='checkout-full-addresses' and not(ancestor::div[1][contains(@class, 'is-hidden')])])[${index}+1] ${addressToUse}
+ IF ${index} == ${ssp_checkout_delivery_address_dropdowns_count} BREAK
+ END
+ END
+ Repeat Keyword 3 Wait For Load State
+ Sleep 500ms
+ END
+ Click ${submit_checkout_form_button}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select the following existing address on the checkout as 'shipping':
+ [Arguments] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${is_ssp}' == 'true'
+ Wait Until Element Is Visible ${checkout_address_delivery_selector}[ssp_b2b]
+ ELSE
+ Wait Until Element Is Visible ${checkout_address_delivery_selector}[${env}]
+ END
+ WHILE '${selected_address}' != '${addressToUse}' limit=5
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ ${selected_address}= Get Text xpath=//select[contains(@name,'shippingAddress')][contains(@id,'addressesForm_shippingAddress_id')]/..//span[contains(@id,'shippingAddress_id')]
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ IF '${is_ssp}' == 'true'
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[ssp_b2b] ${addressToUse}
+ ELSE
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ IF '${is_ssp}' == 'true'
+ ${selected_address}= Get Text xpath=//address-item-form-field-list//select[@name='checkout-full-addresses' and not(ancestor::div[1][contains(@class, 'is-hidden')])]/..//span[contains(@id,'checkout-full-addresses')]
+ ELSE
+ ${selected_address}= Get Text xpath=//div[contains(@class,'shippingAddress')]//select[@name='checkout-full-addresses'][contains(@class,'address__form')]/..//span[contains(@id,'checkout-full-address')]
+ END
+ ELSE
+ Repeat Keyword 2 Select From List By Label ${checkout_address_delivery_selector}[${env}] ${addressToUse}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ Exit For Loop
+ END
+ END
+
+Yves: fill in the following new shipping address:
+ [Documentation] Possible argument names: salutation, firstName, lastName, street, houseNumber, postCode, city, country, company, phone, additionalAddress
+ [Arguments] @{args}
+ ${newAddressData}= Set Up Keyword Arguments @{args}
+ IF '${is_ssp}' == 'true'
+ Select From List By Label ${checkout_address_delivery_selector}[ssp_b2b] Define new address
+ Wait Until Element Is Visible xpath=//*[contains(@data-qa,'address-item-form')]//div[contains(@class,'address-content')][@data-qa='component form']
+ ELSE
+ Select From List By Label ${checkout_address_delivery_selector}[${env}] Define new address
+ Wait Until Element Is Visible ${checkout_new_shipping_address_form}
+ END
+ IF '${is_ssp}' == 'true'
+ VAR ${checkout_shipping_address_salutation_selector} ${ssp_checkout_shipping_address_salutation_selector}
+ VAR ${checkout_shipping_address_last_name_field} ${ssp_checkout_shipping_address_last_name_field}
+ VAR ${checkout_shipping_address_company_name_field} ${ssp_checkout_shipping_address_company_name_field}
+ VAR ${checkout_shipping_address_street_field} ${ssp_checkout_shipping_address_street_field}
+ VAR ${checkout_shipping_address_house_number_field} ${ssp_checkout_shipping_address_house_number_field}
+ VAR ${checkout_shipping_address_additional_address_field} ${ssp_checkout_shipping_address_additional_address_field}
+ VAR ${checkout_shipping_address_zip_code_field} ${ssp_checkout_shipping_address_zip_code_field}
+ VAR ${checkout_shipping_address_city_field} ${ssp_checkout_shipping_address_city_field}
+ VAR ${checkout_shipping_address_country_selector} ${ssp_checkout_shipping_address_country_selector}
+ VAR ${checkout_shipping_address_phone_field} ${ssp_checkout_shipping_address_phone_field}
+ ${checkout_shipping_address_first_name_field}[${env}]= Set Variable ${ssp_checkout_shipping_address_first_name_field}
+ END
+ FOR ${key} ${value} IN &{newAddressData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${checkout_shipping_address_salutation_selector} ${value}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_first_name_field}[${env}] ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_last_name_field} ${value}
+ IF '${key}'=='street' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_street_field} ${value}
+ IF '${key}'=='houseNumber' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_house_number_field} ${value}
+ IF '${key}'=='postCode' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_zip_code_field} ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_city_field} ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label ${checkout_shipping_address_country_selector} ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_company_name_field} ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_phone_field} ${value}
+ IF '${key}'=='additionalAddress' and '${value}' != '${EMPTY}' Type Text ${checkout_shipping_address_additional_address_field} ${value}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+
+Yves: fill in the following new billing address:
+ [Documentation] Possible argument names: salutation, firstName, lastName, street, houseNumber, postCode, city, country, company, phone, additionalAddress
+ [Arguments] @{args}
+ ${newAddressData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Enabled ${checkout_address_billing_selector}[${env}]
+ Select From List By Label ${checkout_address_billing_selector}[${env}] Define new address
+ Wait Until Element Is Visible ${checkout_new_billing_address_form}
+ FOR ${key} ${value} IN &{newAddressData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${checkout_billing_address_salutation_selector} ${value}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_first_name_field} ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_last_name_field} ${value}
+ IF '${key}'=='street' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_street_field} ${value}
+ IF '${key}'=='houseNumber' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_house_number_field} ${value}
+ IF '${key}'=='postCode' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_zip_code_field} ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_city_field} ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label ${checkout_billing_address_country_select} ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_company_name_field} ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_phone_field} ${value}
+ IF '${key}'=='additionalAddress' and '${value}' != '${EMPTY}' Type Text ${checkout_billing_address_additional_address_field} ${value}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+
+Yves: select delivery to multiple addresses
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${is_ssp}' == 'true'
+ VAR ${single_address_per_shipment_type_checkbox_locator} xpath=//toggler-checkbox[contains(@name,'isSingleAddressPerShipmentType')][1]
+ Wait Until Page Contains Element ${single_address_per_shipment_type_checkbox_locator}
+ ${single_address_per_shipment_type_checkbox_is_checked}= Run Keyword And Return Status Page Should Contain Element xpath=//toggler-checkbox[contains(@name,'isSingleAddressPerShipmentType')][1][@checked] timeout=100ms
+ IF '${single_address_per_shipment_type_checkbox_is_checked}'=='True'
+ Click ${single_address_per_shipment_type_checkbox_locator}
+ END
+ ELSE
+ Select From List By Label ${checkout_address_delivery_selector}[${env}] Deliver to multiple addresses
+ END
+
+Yves: select multiple addresses from toggler
+ Wait Until Element Is Visible ${checkout_address_multiple_addresses_toggler_button}
+ Click ${checkout_address_multiple_addresses_toggler_button}
+
+Yves: click checkout button:
+ [Arguments] ${buttonName}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click xpath=//button[@type='submit' and contains(text(),'${buttonName}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: fill in new delivery address for a product:
+ [Documentation] Possible argument names: product (SKU or Name), salutation, firstName, lastName, street, houseNumber, postCode, city, country, company, phone, additionalAddress
+ [Arguments] @{args}
+ ${newAddressData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{newAddressData}
+ ${item}= Set Variable If '${key}'=='product' ${value} ${item}
+ IF '${key}'=='product' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_mp_b2c'] Yves: select xxx shipment type for item xxx: shipment_type=Delivery item=${item}
+ IF '${env}' not in ['ui_suite'] Select From List By Label xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]//select Define new address
+ IF '${env}' in ['ui_suite']
+ Click xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//shipment-type-toggler//span[contains(@class,'label')][contains(.,'Delivery')]
+ Select From List By Label xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//select[contains(@name,'id_customer_address')] Define new address
+ END
+ END
+ IF '${env}' in ['ui_mp_b2c']
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//select[contains(@name,'[salutation]')] ${value}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[first_name]')] ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[last_name]')] ${value}
+ IF '${key}'=='street' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[address1]')] ${value}
+ IF '${key}'=='houseNumber' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[address2]')] ${value}
+ IF '${key}'=='postCode' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[zip_code]')] ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//*[self::input or self::textarea][contains(@name,'[city]')] ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//select[contains(@name,'[iso2_code]')] ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[company]')] ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[phone]')] ${value}
+ IF '${key}'=='additionalAddress' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::article/following-sibling::div[contains(@class,'address-item-form')]//input[contains(@name,'[address3]')] ${value}
+ ELSE IF '${env}' in ['ui_suite']
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//select[contains(@name,'[salutation]')] ${value}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[first_name]')] ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[last_name]')] ${value}
+ IF '${key}'=='street' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[address1]')] ${value}
+ IF '${key}'=='houseNumber' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[address2]')] ${value}
+ IF '${key}'=='postCode' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[zip_code]')] ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//*[self::input or self::textarea][contains(@name,'[city]')] ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//select[contains(@name,'[iso2_code]')] ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[company]')] ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[phone]')] ${value}
+ IF '${key}'=='additionalAddress' and '${value}' != '${EMPTY}' Type Text xpath=//*[contains(@data-qa,'address-item-form-field-list')]/div//strong[contains(.,'${item}')]/ancestor::div[contains(@class,'item-shipping')]//div[@data-qa='component form']//input[contains(@name,'[address3]')] ${value}
+ ELSE
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//select[contains(@name,'[salutation]')] ${value}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[first_name]')] ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[last_name]')] ${value}
+ IF '${key}'=='street' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[address1]')] ${value}
+ IF '${key}'=='houseNumber' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[address2]')] ${value}
+ IF '${key}'=='postCode' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[zip_code]')] ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//*[self::input or self::textarea][contains(@name,'[city]')] ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//select[contains(@name,'[iso2_code]')] ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[company]')] ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[phone]')] ${value}
+ IF '${key}'=='additionalAddress' and '${value}' != '${EMPTY}' Type Text xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]/ancestor::div[contains(@class,'address-item-form')][1]//input[contains(@name,'[address3]')] ${value}
+ END
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+
+Yves: select the following shipping method on the checkout and go next:
+ [Arguments] ${shippingMethod}
+ IF '${env}'=='ui_suite'
+ Click With Options xpath=//input[contains(@id,'shipmentSelection')]/following-sibling::span[contains(@class,'label')][contains(.,'${shippingMethod}')]/../span[contains(@class,'radio__box')] force=True
+ ELSE
+ Click xpath=//div[@data-qa='component shipment-sidebar']//*[contains(.,'Shipping Method')]/../ul//label[contains(.,'${shippingMethod}')]/span[contains(@class,'radio__box')]
+ END
+ Click ${submit_checkout_form_button}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: submit form on the checkout
+ Click ${submit_checkout_form_button}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select the following shipping method for the shipment:
+ [Arguments] ${shipment} ${shippingProvider} ${shippingMethod}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_suite']
+ Click //form[@name='shipmentCollectionForm']/descendant::article[contains(@class,'grid')][${shipment}]/div[last()]//h5[contains(.,'${shippingProvider}')]/following-sibling::ul[1]//label[contains(.,'${shippingMethod}')]/span[contains(@class,'radio__box')]
+ ELSE
+ Click xpath=//form[@name='shipmentCollectionForm']/descendant::article[contains(@class,'grid')][${shipment}]//div[@data-qa='component shipment-sidebar']//*[contains(@class,'title')]/*[contains(text(),'${shippingProvider}')]/..//following-sibling::ul[1]//label[contains(.,'${shippingMethod}')]/span[contains(@class,'radio__box')]
+ END
+
+Yves: select the following payment method on the checkout and go next:
+ [Arguments] ${paymentMethod} ${paymentProvider}=${EMPTY}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}'=='ui_b2b' and '${paymentMethod}'=='Invoice'
+ Click //form[@id='payment-form']//li[@class='checkout-list__item'][contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_invoice_date_of_birth_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_invoice_date_of_birth_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2b'] and '${paymentMethod}'=='Invoice'
+ Click //form[@id='payment-form']//li[@class='checkout-list__item'][contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2b'] and '${paymentMethod}'=='Invoice (Marketplace)'
+ Click //form[@id='payment-form']//li[@class='checkout-list__item'][contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2b'] and '${paymentMethod}'=='Marketplace Invoice'
+ Click //form[@id='payment-form']//li[@class='checkout-list__item'][contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF ('${env}'=='ui_suite' and '${paymentProvider}'!='${EMPTY}')
+ Click //form[@name='paymentForm']//h5[contains(text(), '${paymentProvider}')]/following-sibling::ul//label/span[contains(text(), '${paymentMethod}')]
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}'=='ui_mp_b2c' and '${paymentMethod}'=='Credit Card'
+ Click //form[@name='paymentForm']//toggler-radio[contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Type Text ${checkout_payment_card_number_field} 4111111111111111
+ Type Text ${checkout_payment_name_on_card_field} First Last
+ Select From List By Value ${checkout_payment_card_expires_month_select} 01
+ Select From List By Value ${checkout_payment_card_expires_year_select} 2025
+ Type Text ${checkout_payment_card_security_code_field} 123
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2c'] and '${paymentMethod}'=='Invoice'
+ Click //form[@name='paymentForm']//toggler-radio[contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_invoice_date_of_birth_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_invoice_date_of_birth_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2c'] and '${paymentMethod}'=='Invoice (Marketplace)'
+ Click //form[@name='paymentForm']//toggler-radio[contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE IF '${env}' in ['ui_mp_b2c'] and '${paymentMethod}'=='Marketplace Invoice'
+ Click //form[@name='paymentForm']//toggler-radio[contains(.,'${paymentMethod}')]//span[contains(@class,'toggler-radio__box')]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ Click ${submit_checkout_form_button}[${env}]
+ ELSE
+ IF '${paymentMethod}' == 'Invoice' or '${paymentMethod}' == 'invoice'
+ ${payment_method_index}= Set Variable last()
+ Click xpath=(//form[@name='paymentForm']//span[contains(@class,'toggler') and contains(text(),'${paymentMethod}')]/preceding-sibling::span[@class='toggler-radio__box'])[${payment_method_index}]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_invoice_date_of_birth_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_invoice_date_of_birth_field} 11.11.2000
+ ELSE
+ ${payment_method_index}= Set Variable position()=1
+ Click xpath=(//form[@name='paymentForm']//span[contains(@class,'toggler') and contains(text(),'Invoice')]/preceding-sibling::span[@class='toggler-radio__box'])[${payment_method_index}]
+ Disable Automatic Screenshots on Failure
+ ${date_of_birth_present}= Run Keyword And Ignore Error Page Should Contain Element ${checkout_payment_marketplace_invoice_date_field} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $date_of_birth_present Type Text ${checkout_payment_marketplace_invoice_date_field} 11.11.2000
+ END
+ Click ${submit_checkout_form_button}[${env}]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: '${checkoutAction}' on the summary page
+ [Documentation] Possible supported actions: 'submit the order', 'send the request' and 'approve the cart'
+ IF '${checkoutAction}' == 'submit the order'
+ Click ${checkout_summary_submit_order_button}
+ ELSE IF '${checkoutAction}' == 'send the request'
+ Click ${checkout_summary_send_request_button}
+ ELSE IF '${checkoutAction}' == 'approve the cart'
+ Click ${checkout_summary_approve_request_button}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select approver on the 'Summary' page:
+ [Arguments] ${approver}
+ Wait Until Element Is Visible ${checkout_summary_approver_dropdown}
+ Select From List By Label ${checkout_summary_approver_dropdown} ${approver}
+
+Yves: 'Summary' page contains/doesn't contain:
+ [Arguments] ${condition} @{checkout_summary_elements_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${checkout_summary_elements_list_count}= get length ${checkout_summary_elements_list}
+ FOR ${index} IN RANGE 0 ${checkout_summary_elements_list_count}
+ ${checkout_summary_element_to_check}= Get From List ${checkout_summary_elements_list} ${index}
+ IF '${condition}' == 'true'
+ Run Keywords
+ Log ${checkout_summary_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Contain Element ${checkout_summary_element_to_check} message=${checkout_summary_element_to_check} is not displayed
+ END
+ IF '${condition}' == 'false'
+ Run Keywords
+ Log ${checkout_summary_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Not Contain Element ${checkout_summary_element_to_check} message=${checkout_summary_element_to_check} should not be displayed
+ END
+ END
+
+Yves: proceed with checkout as guest:
+ [Arguments] ${salutation} ${firstName} ${lastName} ${email}
+ Wait Until Page Contains Element xpath=//toggler-radio[contains(@data-qa,'checkoutProceedAs')][contains(@data-qa,'guest')]//input
+ Click Element by xpath with JavaScript //toggler-radio[contains(@data-qa,'checkoutProceedAs')][contains(@data-qa,'guest')]//input
+ Wait Until Element Is Visible ${yves_checkout_login_guest_firstName_field}
+ Type Text ${yves_checkout_login_guest_firstName_field} ${firstName}
+ Type Text ${yves_checkout_login_guest_lastName_field} ${lastName}
+ Type Text ${yves_checkout_login_guest_email_field} ${email}
+ Yves: accept the terms and conditions: true isGuest=true
+ Click ${yves_checkout_login_buy_as_guest_submit_button}
+
+Yves: assert merchant of product in cart or list:
+ [Documentation] Method for MP which asserts value in 'Sold by' label of item in cart or list. Requires concrete SKU
+ [Arguments] ${sku} ${merchant_name_expected}
+ Page Should Contain Element xpath=(//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::*[self::article or self::tr or self::product-item][contains(@itemtype,'Product')]//a[contains(@href,'merchant')][contains(text(),'${merchant_name_expected}')])[1] timeout=${browser_timeout}
+
+Yves: save new delivery address to address book:
+ [Arguments] ${state}
+ ${state}= Convert To Lower Case ${state}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b'] Wait Until Page Contains Element ${manage_your_addresses_link}
+ ${checkboxState}= Set Variable ${EMPTY}
+ IF '${is_ssp}' == 'true'
+ ${checkboxState}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(@data-qa,'address-item-form')]//input[contains(@name,'[shippingAddress][isAddressSavingSkipped]')][@checked] timeout=100ms
+ ELSE
+ ${checkboxState}= Run Keyword And Return Status Page Should Contain Element xpath=//input[@id='addressesForm_shippingAddress_isAddressSavingSkipped'][@checked] timeout=100ms
+ END
+ IF '${checkboxState}'=='False' and '${state}' == 'true'
+ IF '${is_ssp}' == 'true'
+ Click xpath=//*[contains(@data-qa,'address-item-form')]//input[contains(@name,'[shippingAddress][isAddressSavingSkipped]')]/ancestor::span[contains(@data-qa,'checkbox')]
+ ELSE
+ Click xpath=//input[@id='addressesForm_shippingAddress_isAddressSavingSkipped']/ancestor::span[contains(@data-qa,'checkbox')]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${checkboxState}'=='True' and '${state}' == 'false'
+ IF '${is_ssp}' == 'true'
+ Click xpath=//*[contains(@data-qa,'address-item-form')]//input[contains(@name,'[shippingAddress][isAddressSavingSkipped]')]/ancestor::span[contains(@data-qa,'checkbox')]
+ ELSE
+ Click xpath=//input[@id='addressesForm_shippingAddress_isAddressSavingSkipped']/ancestor::span[contains(@data-qa,'checkbox')]
+ END
+
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: save new billing address to address book:
+ [Arguments] ${state}
+ ${state}= Convert To Lower Case ${state}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b'] Wait Until Page Contains Element ${manage_your_addresses_link}
+ ${checkboxState}= Set Variable ${EMPTY}
+ ${checkboxState}= Run Keyword And Return Status Page Should Contain Element xpath=//input[@id='addressesForm_billingAddress_isAddressSavingSkipped'][@checked] timeout=100ms
+ IF '${checkboxState}'=='False' and '${state}' == 'true'
+ Click xpath=//input[@id='addressesForm_billingAddress_isAddressSavingSkipped']/ancestor::span[contains(@data-qa,'checkbox')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${checkboxState}'=='True' and '${state}' == 'false'
+ Click xpath=//input[@id='addressesForm_billingAddress_isAddressSavingSkipped']/ancestor::span[contains(@data-qa,'checkbox')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: return to the previous checkout step:
+ [Arguments] ${checkoutStep}
+ ${checkoutStep}= Convert To Lower Case ${checkoutStep}
+ Click //ul[@data-qa='component breadcrumb']//a[contains(@href,'${checkoutStep}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: check that the payment method is/not present in the checkout process:
+ [Arguments] ${payment_method_locator} ${condition}
+ ${condition}= Convert To Lower Case ${condition}
+ IF '${condition}' == 'true'
+ Page Should Contain Element ${payment_method_locator}
+ ELSE IF '${condition}' == 'false'
+ Page Should not Contain Element ${payment_method_locator}
+ END
+
+ Yves: proceed as a guest user and login during checkout:
+ [Arguments] ${email} ${password}=${default_password}
+ IF '${env}' in ['ui_suite']
+ Wait Until Page Contains Element ${email_field}
+ Type Text ${email_field} ${email}
+ Type Text ${password_field} ${password}
+ Click ${form_login_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ELSE
+ Wait Until Page Contains Element ${yves_checkout_login_tab}
+ Click ${yves_checkout_login_tab}
+ Type Text ${email_field} ${email}
+ Type Text ${password_field} ${password}
+ Click ${form_login_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: signup guest user during checkout:
+ [Arguments] ${firstName} ${lastName} ${email} ${password} ${confirmpassword}
+ Wait Until Page Contains Element ${yves_checkout_signup_button}
+ Click ${yves_checkout_signup_button}
+ Type Text ${yves_checkout_signup_first_name} ${firstname}
+ Type Text ${yves_checkout_signup_last_name} ${lastname}
+ Type Text ${yves_checkout_signup_email} ${email}
+ Type Text ${yves_checkout_signup_password} ${password}
+ Type Text ${yves_checkout_signup_confirm_password} ${confirmpassword}
+ Wait Until Element Is Visible ${yves_checkout_signup_accept_terms}
+ Check Checkbox ${yves_checkout_signup_accept_terms}
+ Click ${yves_checkout_signup_tab}
+
+Yves: select xxx shipment type for item number xxx:
+ [Arguments] ${shipment_type} ${item_number}
+ ${item_number}= Evaluate ${item_number}-1
+ Wait Until Element Is Visible xpath=//input[contains(@id,'addressesForm_multiShippingAddresses_${item_number}')]/following-sibling::span[contains(text(), '${shipment_type}')]
+ Click xpath=//input[contains(@id,'addressesForm_multiShippingAddresses_${item_number}')]/following-sibling::span[contains(text(), '${shipment_type}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select xxx shipment type for item xxx:
+ [Arguments] ${shipment_type} ${item}
+ Click xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${item}')]//shipment-type-toggler//span[contains(@data-qa,'shipmentType')]//span[contains(text(), '${shipment_type}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select xxx shipment type on checkout:
+ [Arguments] ${shipment_type}
+ Click With Options xpath=(//form[@name='addressesForm']//shipment-type-toggler//span[contains(@data-qa,'shipmentType')]//span[contains(text(), '${shipment_type}')])[1] force=True
+ TRY
+ Repeat Keyword 2 Wait For Load State
+ Repeat Keyword 2 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: check store availability for item number xxx:
+ [Arguments] @{args}
+ ${availabilityData}= Set Up Keyword Arguments @{args}
+ ${item_number}= Set Variable 1
+ FOR ${key} ${value} IN &{availabilityData}
+ IF '${key}'=='item_number' and '${value}' != '${EMPTY}'
+ ${item_number}= Set Variable ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_suite']
+ Click xpath=(//*[contains(@data-qa,'address-item-form')][contains(@class,'list')]/div)[${item_number}]//shipment-type-toggler//service-point-selector[contains(@data-qa,'service-point-selector')]/div[contains(@class,'no-location')]/button
+ Sleep 2s
+ Fill Text xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//input[contains(@class,'search')])[1] ${value} force=True
+ ELSE
+ Click xpath=(//article)[${item_number}]//shipment-type-toggler//service-point-selector[contains(@data-qa,'service-point-selector')]
+ Sleep 2s
+ Fill Text xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//input[contains(@class,'search')])[1] ${value} force=True
+ END
+ Keyboard Key press Enter
+ Sleep 2s
+ TRY
+ Repeat Keyword 5 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${key}'=='availability' and '${value}' != '${EMPTY}'
+ ${value}= Convert To Lower Case ${value}
+ IF '${value}' == 'green'
+ Page Should Contain Element xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//*[contains(@data-qa,'service-point-availability-status')]//span[contains(@class,'all-items-available')])[1]
+ # ELSE IF '${value}' == 'yellow'
+ # Page Should Contain Element xpath=
+ # ELSE IF '${value}' == 'red'
+ # Page Should Contain Element xpath=
+ END
+ END
+ END
+ Click With Options xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//button[contains(@class,'close')][contains(@class,'main-popup')])[1] force=True
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: select pickup service point store for item number xxx:
+ [Arguments] @{args}
+ ${servicePointData}= Set Up Keyword Arguments @{args}
+ ${item_number}= Set Variable 1
+ FOR ${key} ${value} IN &{servicePointData}
+ IF '${key}'=='item_number' and '${value}' != '${EMPTY}'
+ ${item_number}= Set Variable ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_suite']
+ Click xpath=(//*[contains(@data-qa,'address-item-form')][contains(@class,'list')]/div)[${item_number}]//shipment-type-toggler//service-point-selector[contains(@data-qa,'service-point-selector')]/div[contains(@class,'no-location')]/button
+ Sleep 2s
+ Fill Text xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//input[contains(@class,'search')])[1] ${value} force=True
+ ELSE
+ Click xpath=(//article)[${item_number}]//shipment-type-toggler//service-point-selector[contains(@data-qa,'service-point-selector')]
+ Sleep 2s
+ Fill Text xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//input[contains(@class,'search')])[1] ${value} force=True
+ END
+ Keyboard Key press Enter
+ Sleep 2s
+ TRY
+ Repeat Keyword 5 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click With Options xpath=((//div[contains(@id,'service-point-selector')])[${item_number}]//button[contains(@class,'select-button')])[position()=1] force=true
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ END
+
+Yves: checkout summary page contains product with unit price:
+ [Arguments] ${sku} ${productName} ${productPrice}
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ TRY
+ Page Should Contain Element xpath=//div[contains(@class,'product-card-item__col--description')]//div[contains(.,'SKU: ${sku}')]/ancestor::article//*[contains(@class,'product-card-item__col--description')]/div[1]//*[contains(@class,'money-price__amount')][contains(.,'${productPrice}')] timeout=100ms
+ EXCEPT
+ Page Should Contain Element xpath=//div[contains(@class,'product-cart-item__col--description')]//div[contains(.,'SKU: ${sku}')]/ancestor::article//*[contains(@class,'product-cart-item__col--description')]/div[1]//*[contains(@class,'money-price__amount')][contains(.,'${productPrice}')] timeout=100ms
+ END
+ ELSE IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//*[contains(@data-qa,'summary-node')]//div[contains(.,'${productName}')]/ancestor::*[contains(@data-qa,'summary-node')]//strong[contains(.,'${productPrice}')]
+ ELSE
+ Page Should Contain Element xpath=//article[contains(@data-qa,'component product-card-item')]//*[contains(text(),'${productName}')]/following-sibling::span/span[contains(@class,'money-price__amount') and contains(.,'${productPrice}')] timeout=1s
+ END
+
+Yves: checkout summary step contains product with unit price:
+ [Arguments] ${productName} ${productPrice}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Page Should Contain Element xpath=(//*[contains(@data-qa,'summary-node')]//div[contains(.,'${productName}')]/ancestor::*[contains(@data-qa,'summary-node')]//strong[contains(.,'${productPrice}')])[1]
diff --git a/atest/testdata/performance/resources/steps/cms_steps.robot b/atest/testdata/performance/resources/steps/cms_steps.robot
new file mode 100644
index 0000000..7e4f0fa
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/cms_steps.robot
@@ -0,0 +1,78 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library JSONLibrary
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Get latest cms page version data by uuid
+ [Documentation] This keyword gets the latest cms page version data by uuid from the DB table `spy_cms_version`.
+ ... *Example:*
+ ...
+ ... ``Get latest cms page version data by uuid uuid=10014bd9-4bba-5a54-b84f-31b4b7efd064``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ ${data} Query SELECT fk_cms_page, version, data from spy_cms_version JOIN spy_cms_page ON spy_cms_version.fk_cms_page = spy_cms_page.id_cms_page WHERE spy_cms_page.uuid = '${uuid}' ORDER BY version DESC LIMIT 1;
+ Disconnect From Database
+ RETURN ${data[0]}
+
+Add content product abstract list to cms page in DB
+ [Documentation] This keyword adds conctent product abstarct list to a given CMS page in the DB table `spy_cms_version`.
+ ... *Example:*
+ ...
+ ... ``Add content product abstract list to cms page in DB uuid=10014bd9-4bba-5a54-b84f-31b4b7efd064 content_product_abstract_list_key=apl-1``
+ ...
+ [Arguments] ${uuid} ${content_product_abstract_list_key}=apl-1
+ ${data} Get latest cms page version data by uuid ${uuid}
+ ${cms_page_data_json}= Convert String to JSON ${data[2]}
+ FOR ${glossary_attributes} IN @{cms_page_data_json['cms_glossary']['glossary_attributes']}
+ FOR ${translation} IN @{glossary_attributes['translations']}
+ IF '${glossary_attributes['placeholder']}' == 'content'
+ Set To Dictionary ${translation} translation={{ content_product_abstract_list("${content_product_abstract_list_key}", "bottom-title") }}
+ END
+ ${new_translation}= Replace special chars ${translation['translation']}
+ Set To Dictionary ${translation} translation=${new_translation}
+ END
+ END
+ ${cms_page_data}= Evaluate json.dumps(${cms_page_data_json}) json
+ ${new_id}= Get next id from table spy_cms_version id_cms_version
+ ${new_version}= Evaluate ${data[1]} + 1
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_cms_version (fk_cms_page, data, version, version_name) value (${data[0]}, '${cms_page_data}', ${new_version}, 'v. ${new_version}');
+ ELSE
+ Execute Sql String INSERT INTO spy_cms_version (id_cms_version, fk_cms_page, data, version, version_name) VALUES (${new_id}, ${data[0]}, '${cms_page_data}', ${new_version}, 'v. ${new_version}');
+ END
+ Disconnect From Database
+ Trigger publish trigger-events cms_page
+
+Delete latest cms page version by uuid from DB
+ [Documentation] This keyword deletes the latest cms page version data by uuid from in the DB table `spy_cms_version`.
+ ... *Example:*
+ ...
+ ... ``Delete latest cms page version by uuid from DB uuid=10014bd9-4bba-5a54-b84f-31b4b7efd064``
+ ...
+ [Arguments] ${uuid}
+ ${data} Get latest cms page version data by uuid ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_cms_version WHERE fk_cms_page = ${data[0]} AND version = ${data[1]};
+ Disconnect From Database
+ Trigger publish trigger-events cms_page
+
+Replace special chars
+ [Documentation] This keyword replaces special chars in the given string.
+ ... *Example:*
+ ...
+ ... ``Replace special chars input_string=Input string with special chars: & < > ' "``
+ ...
+ [Arguments] ${input_string}
+ ${converted_string}= Replace String ${input_string} & \\u0026
+ ${converted_string}= Replace String ${converted_string} < \\u003C
+ ${converted_string}= Replace String ${converted_string} > \\u003E
+ ${converted_string}= Replace String ${converted_string} ' \\u0027
+ IF '${db_engine}' == 'pymysql'
+ ${converted_string}= Replace String ${converted_string} " \\u0022
+ END
+ RETURN ${converted_string}
diff --git a/atest/testdata/performance/resources/steps/company_steps.robot b/atest/testdata/performance/resources/steps/company_steps.robot
new file mode 100644
index 0000000..e36c7bc
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/company_steps.robot
@@ -0,0 +1,219 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_yves.robot
+Resource ../common/common_zed.robot
+Resource ../pages/zed/zed_attach_to_business_unit_page.robot
+Resource ../pages/yves/yves_customer_account_page.robot
+Resource ../pages/zed/zed_delete_company_user_page.robot
+Resource ../pages/zed/zed_create_company_page.robot
+Resource ../pages/zed/zed_create_company_business_unit_page.robot
+Resource ../pages/zed/zed_create_company_role_page.robot
+Resource ../pages/zed/zed_create_company_user_page.robot
+Resource ../pages/yves/yves_company_role_page.robot
+Resource ../pages/yves/yves_company_business_unit_page.robot
+Resource ../pages/yves/yves_company_user_page.robot
+
+*** Keywords ***
+Zed: create new Company Business Unit for the following company:
+ [Documentation] Creates new company BU with provided BU Name and for provided company.
+ [Arguments] ${company_name} ${business_unit_name} ${company_id}=EMPTY ${parent_business_unit}=parent
+ Zed: go to URL: /company-business-unit-gui/list-company-business-unit
+ Zed: click button in Header: Create Company Business Unit
+ ${is_company_dropdown_with_search}= Run Keyword And Return Status Page Should Contain Element ${zed_bu_company_dropdown_with_search_locator} timeout=0.5s
+ IF ${is_company_dropdown_with_search}
+ Click ${zed_bu_company_dropdown_with_search_locator}
+ Type Text ${zed_bu_company_search_field} ${company_name}
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Sleep 0.5s
+ ELSE
+ Click ${zed_bu_company_dropdown_locator}
+ Select From List By Label Contains ${zed_bu_company_dropdown_locator} ${company_name}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Select From List By Label Contains ${zed_bu_parent_bu_dropdown_locator} ${parent_business_unit}
+ END
+ VAR ${created_business_unit} ${business_unit_name}+${random} scope=TEST
+ Type Text ${zed_bu_name_field} ${created_business_unit}
+ Type Text ${zed_bu_iban_field} testiban+${random}
+ Type Text ${zed_bu_bic_field} testbic+${random}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_success_flash_message}
+ Wait Until Element Is Visible ${zed_table_locator}
+ Zed: perform search by: ${created_business_unit}
+ Table Should Contain ${zed_table_locator} ${created_business_unit}
+ ${newly_created_business_unit_id}= Get Text xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${created_business_unit}')]/../td[1]
+ VAR ${created_business_unit_id} ${newly_created_business_unit_id} scope=TEST
+
+Zed: create new Company with provided name:
+ [Arguments] ${company_name}
+ ${currentURL}= Get Location
+ IF '/company-gui/list-company' not in '${currentURL}' Zed: go to URL: /company-gui/list-company
+ Zed: click button in Header: Create Company
+ VAR ${created_company}= ${company_name}+${random} scope=TEST
+ Type Text ${zed_company_name_input_field} ${created_company}
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_success_flash_message}
+ Wait Until Element Is Visible ${zed_table_locator}
+ Table Should Contain ${zed_table_locator} ${created_company}
+ ${newly_created_company_id}= Get Text xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${created_company}')]/../td[1]
+ VAR ${created_company_id} ${newly_created_company_id} scope=TEST
+
+Zed: create new Company Role with provided permissions:
+ [Documentation] Creates new company role with provided permission. Permissions are optional
+ [Arguments] ${company_name} ${company_id} ${role_name} ${is_default} @{permissions_list} ${permission1}=${EMPTY} ${permission2}=${EMPTY} ${permission3}=${EMPTY} ${permission4}=${EMPTY} ${permission5}=${EMPTY} ${permission6}=${EMPTY} ${permission7}=${EMPTY} ${permission8}=${EMPTY} ${permission9}=${EMPTY} ${permission10}=${EMPTY} ${permission11}=${EMPTY} ${permission12}=${EMPTY} ${permission13}=${EMPTY} ${permission14}=${EMPTY} ${permission15}=${EMPTY}
+ Zed: go to URL: /company-role-gui/list-company-role
+ Zed: click button in Header: Add company user role
+ ${new_list_of_permissions}= Get Length ${permissions_list}
+ IF '${is_default}'=='true' Zed: Check checkbox by Label: Is Default
+ FOR ${index} IN RANGE 0 ${new_list_of_permissions}
+ ${permission_to_set}= Get From List ${permissions_list} ${index}
+ Zed: Check checkbox by Label: ${permission_to_set}
+ END
+ ${is_company_dropdown_with_search}= Run Keyword And Return Status Page Should Contain Element ${zed_role_company_dropdown_with_search_locator} timeout=0.5s
+ IF ${is_company_dropdown_with_search}
+ Click ${zed_role_company_dropdown_with_search_locator}
+ Type Text ${zed_role_company_search_field} ${company_name}
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${company_name}') and contains(text(),'${company_id}')]
+ Sleep 0.5s
+ ELSE
+ Click ${zed_role_company_dropdown_locator}
+ Select From List By Label Contains ${zed_role_company_dropdown_locator} ${company_name}
+ END
+ VAR ${created_company_role} ${role_name}+${random} scope=TEST
+ Type Text ${zed_role_name_field} ${created_company_role}
+ Zed: submit the form
+
+Zed: Create new Company User with provided details:
+ [Arguments] @{args}
+ ${company_user_data}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /company-user-gui/list-company-user
+ Wait Until Element Is Visible ${zed_table_locator}
+ Zed: click button in Header: Add User
+ FOR ${key} ${value} IN &{company_user_data}
+ ${key}= Convert To Lower Case ${key}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${zed_create_company_user_email_field} ${value}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Value ${zed_create__company_user_salutation_dropdown} ${value}
+ IF '${key}'=='first_name' and '${value}' != '${EMPTY}' Type Text ${zed_create_company_user_first_name_field} ${value}
+ IF '${key}'=='last_name' and '${value}' != '${EMPTY}' Type Text ${zed_create_company_user_last_name_field} ${value}
+ IF '${key}'=='gender' and '${value}' != '${EMPTY}' Select From List By Value ${zed_create_company_user_gender_dropdown} ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}'
+ Click ${zed_create_company_user_company_name_dropdown}
+ Type Text ${zed_create_company_user_company_search_field} ${value}
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Sleep 0.5s
+ END
+ IF '${key}'=='business_unit' and '${value}' != '${EMPTY}'
+ Click ${zed_create_company_business_unit_dropdown}
+ Type Text ${zed_create_company_business_unit_search_field} ${value}
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${value}')]
+ Sleep 0.5s
+ END
+ IF '${key}'=='role' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ END
+ Zed: submit the form
+
+Zed: attach company user to the following BU with role:
+ [Arguments] ${business_unit} ${role_checkbox}
+ Wait Until Element Is Visible ${zed_business_unit_selector}
+ IF '${env}' in ['ui_suite']
+ Click ${zed_attach_customer_to_bu_business_unit_span}
+ Wait Until Element Is Visible ${zed_edit_company_user_search_select_field}
+ Type Text ${zed_edit_company_user_search_select_field} ${business_unit}
+ Click xpath=(//input[@type='search']/../..//ul[contains(.,'${business_unit}')])[1]
+ ELSE
+ Select From List By Label Contains ${zed_business_unit_selector} ${business_unit}
+ END
+ Zed: Check checkbox by Label: ${role_checkbox}
+ Zed: submit the form
+
+
+Yves: 'Business Unit' dropdown contains:
+ [Arguments] @{business_units_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${business_units_list_count}= get length ${business_units_list}
+ FOR ${index} IN RANGE 0 ${business_units_list_count}
+ ${business_unit_to_check}= Get From List ${business_units_list} ${index}
+ Page Should Contain Element //select[@id='company_user_account_selector_form_companyUserAccount']/option[contains(.,'${business_unit_to_check}')]
+ END
+
+Zed: delete company user xxx withing xxx company business unit:
+ [Documentation] Possible argument names: company user name
+ [Arguments] ${companyUserName} ${companyBusinessUnit} ${admin_email}=${zed_admin_email}
+ ${currentURL}= Get Location
+ ${dynamic_admin_user_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ IF ${dynamic_admin_user_exists} and '${admin_email}' == '${zed_admin_email}'
+ VAR ${admin_email} ${dynamic_admin_user}
+ ELSE IF not ${dynamic_admin_user_exists}
+ VAR ${admin_email} ${zed_admin_email}
+ END
+ IF '${zed_url}' not in '${currentURL}' or '${zed_url}security-gui/login' in '${currentURL}'
+ Zed: login on Zed with provided credentials: ${admin_email}
+ END
+ Zed: go to URL: /company-user-gui/list-company-user
+ Zed: perform search by: ${companyUserName}
+ ${customerExists}= Run Keyword And Return Status Table should contain ${zed_table_locator} ${companyBusinessUnit}
+ IF '${customerExists}'=='True'
+ Run keywords
+ Zed: click Action Button(without search) in a table for row that contains: ${companyBusinessUnit} Delete
+ Click ${zed_confirm_delete_company_user_button}
+ END
+
+Yves: create new company role:
+ [Arguments] ${role_name}
+ Yves: go to URL: /company/company-role
+ Click ${create_company_role_button}
+ Type Text ${create_company_role_name_field} ${role_name}
+ Click ${create_company_role_submit_button}
+
+Yves: assign the following permissions to the company role:
+ [Arguments] ${company_role} @{permissions_list}
+ Yves: go to URL: /company/company-role
+ Page Should Contain Element ${company_roles_table_locator}
+ Click xpath=//*[contains(@data-qa,'role-table')]//table//td[contains(.,'${company_role}')]/ancestor::tr//td//a[contains(@href,'update')]
+ Page Should Contain Element ${create_company_role_name_field}
+ ${list_of_permissions}= Get Length ${permissions_list}
+ FOR ${index} IN RANGE 0 ${list_of_permissions}
+ ${permission_to_set}= Get From List ${permissions_list} ${index}
+ Click xpath=//*[contains(@data-qa,'permission-table')]//table//td[contains(.,'${permission_to_set}')]/ancestor::tr//td//button
+ Sleep 0.5s
+ END
+ Click ${create_company_role_submit_button}
+
+Yves: create new company business unit:
+ [Arguments] ${business_unit_name} ${business_unit_email}
+ Yves: go to URL: /company/business-unit
+ Click ${create_company_business_unit_button}
+ Type Text ${create_company_business_unit_name_field} ${business_unit_name}
+ Type Text ${create_company_business_unit_email_field} ${business_unit_email}
+ Click ${create_company_business_unit_submit_button}
+ Page Should Contain Element ${company_business_unit_delete_button}
+
+Yves: create new company user:
+ [Arguments] ${business_unit} ${role} ${email} ${first_name} ${last_name}
+ Yves: go to URL: /company/user
+ Click ${create_company_user_button}
+ Select From List By Label Contains ${create_company_user_business_unit_dropdown} ${business_unit}
+ Click //input[contains(@id,'company_role_collection')]/ancestor::label[contains(.,'${role}')]
+ Sleep 0.5s
+ Type Text ${create_company_user_email_field} ${email}
+ Type Text ${create_company_user_first_name_field} ${first_name}
+ Type Text ${create_company_user_last_name_field} ${last_name}
+ Click ${create_company_user_submit_button}
+ Page Should Not Contain Element ${create_company_user_email_field} message=Failed to create a new company user
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/configurable_bundle_steps.robot b/atest/testdata/performance/resources/steps/configurable_bundle_steps.robot
new file mode 100644
index 0000000..19446a4
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/configurable_bundle_steps.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_yves.robot
+Resource ../pages/yves/yves_bundle_configurator_page.robot
+
+*** Keywords ***
+Yves: choose bundle template to configure:
+ [Arguments] ${bundleTemplate}
+ Click xpath=//div[@data-qa='component template-list']//*[@class='template-list__item-name'][text()='${bundleTemplate}']/ancestor::a
+ Wait Until Element Is Visible ${bundle_configurator_main_content_locator}
+
+Yves: select product in the bundle slot:
+ [Arguments] ${slot} ${sku}
+ Click xpath=//form[@name='configurator_state_form']//button[contains(.,'${slot}')]
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Click xpath=//product-item-list[@data-qa='component configurator-product']//span[@class='configurator-product__sku'][text()='Sku: ${sku}']/ancestor::product-item-list//button
+ ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Click xpath=(//product-item-list[@data-qa='component configurator-product']//span[contains(text(),'${sku}')]/ancestor::product-item-list//button)[1]
+ ELSE
+ Click xpath=//product-item//*[@itemprop='sku'][contains(text(),'${sku}')]/ancestor::product-item//button
+ END
+
+Yves: go to 'Summary' step in the bundle configurator
+ Click ${bundle_configurator_summary_step}
+
+Yves: add products to the shopping cart in the bundle configurator
+ Wait Until Element Is Visible ${bundle_configurator_add_to_cart_button}
+ Click ${bundle_configurator_add_to_cart_button}
+ Yves: remove flash messages
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/configurable_product_steps.robot b/atest/testdata/performance/resources/steps/configurable_product_steps.robot
new file mode 100644
index 0000000..6cc96e4
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/configurable_product_steps.robot
@@ -0,0 +1,200 @@
+*** Settings ***
+Resource ../common/common_ui.robot
+Resource ../../resources/pages/yves/yves_product_configurator_page.robot
+Resource ../../resources/pages/yves/yves_product_details_page.robot
+Resource ../../resources/pages/zed/zed_order_details_page.robot
+
+*** Keywords ***
+Yves: change the product options in configurator to:
+ [Documentation] fill the fields for product configuration (it is possible to set price OR option name).
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${pdp_configure_button}
+ FOR ${key} ${value} IN &{configurationData}
+ ${key}= Convert To Lower Case ${key}
+ IF '${env}' in ['ui_suite']
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Option One']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Option Two']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Adjustable shelves']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Lockers']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ ELSE
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Barebone']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Processor']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option three' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='GPU']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option four' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='External Drive']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option five' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Operating system']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option six' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='W-LAN']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option seven' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Memory']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option eight' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='SSD']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option nine' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Hard disk drive (HDD)']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')]/span[contains(text(), '${value}')]
+ IF '${key}'=='option ten' and '${value}' != '${EMPTY}' Click xpath=//div[contains(@class, 'configurator')]//app-configurator-group/div[@class='group__heading'][h3='Keyboard']/following-sibling::div[@class='group__section']//label[contains(@class,'tile__inner')][contains(text(), '${value}')]
+ END
+ END
+ ### sleep 1 seconds to process background event
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+
+Yves: change the product configuration to:
+ [Documentation] fill the fields for product configuration.
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ Click ${pdp_configure_button}
+ Wait Until Element Is Visible ${configurator_date_input}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${key}'=='date' and '${value}' != '${EMPTY}' Type Text ${configurator_date_input} ${value}
+ IF '${key}'=='date' and '${value}' == '${EMPTY}' Clear Text ${configurator_date_input}
+ IF '${key}'=='date_time' and '${value}' != '${EMPTY}' Select From List By Label ${configurator_day_time_selector} ${value}
+ END
+ Click ${configurator_day_time_selector}
+ ### sleep 1 seconds to process background event
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ Click ${configurator_save_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${pdp_configure_button}
+
+
+Yves: save product configuration
+ Click ${configurator_save_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${pdp_configure_button}
+
+Yves: product configuration notification is:
+ [Arguments] ${expected_notification}
+ Element Text Should Be ${configurator_configuration_status} ${expected_notification}
+
+Yves: back to PDP and not save configuration
+ Click ${configurator_back_button}
+ Click ${unsaved_product_configurations_leave_button}
+
+Yves: product configuration price should be:
+ [Arguments] ${expectedProductPrice}
+ ${price_displayed}= Run Keyword And Ignore Error Page Should Contain Element ${configurator_price_element_locator} timeout=400ms
+ ${actualProductPrice}= Get Text ${configurator_price_element_locator}
+ ${result}= Run Keyword And Ignore Error Should Be Equal ${expectedProductPrice} ${actualProductPrice}
+
+Yves: product configuration status should be equal:
+ [Arguments] ${expected_status}
+ Element Text Should Be ${pdp_configuration_status} ${expected_status}
+
+Yves: configuration should be equal:
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${pdp_configure_button}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${env}' in ['ui_suite']
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Element Should Contain ${pdp_configuration_option_one}[${env}] ${value}
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Element Should Contain ${pdp_configuration_option_two}[${env}] ${value}
+ ELSE
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Element Text Should Be ${pdp_configuration_option_one}[${env}] ${value}
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Element Text Should Be ${pdp_configuration_option_two}[${env}] ${value}
+ END
+ END
+
+Yves: configuration for concrete product should be equal:
+ [Arguments] @{args} ${concrete_sku}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${pdp_configure_button}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${env}' in ['ui_suite']
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Element Should Contain ${pdp_configuration_option_one}[${env}] ${value}
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Element Should Contain ${pdp_configuration_option_two}[${env}] ${value}
+ ELSE
+ IF '${key}'=='option one' and '${value}' != '${EMPTY}' Element Text Should Be ${pdp_configuration_option_one}[${env}] ${value}
+ IF '${key}'=='option two' and '${value}' != '${EMPTY}' Element Text Should Be ${pdp_configuration_option_two} [${env}] ${value}
+ END
+ END
+
+Yves: check and go back that configuration page contains:
+ [Arguments] @{args}
+ ${configuratorData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${pdp_configure_button}
+ Click ${pdp_configure_button}
+ FOR ${key} ${value} IN &{configuratorData}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Element Should Contain ${configurator_store} ${value}
+ IF '${key}'=='locale' and '${value}' != '${EMPTY}' Element Should Contain ${configurator_locale} ${value}
+ IF '${key}'=='price_mode' and '${value}' != '${EMPTY}' Element Should Contain ${configurator_price_mode} ${value}
+ IF '${key}'=='currency' and '${value}' != '${EMPTY}' Element Should Contain ${configurator_currency} ${value}
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}' Element Should Contain ${configurator_sku} ${value}
+ END
+ Click ${configurator_back_button}
+ Wait Until Element Is Visible ${pdp_configure_button}
+
+
+Zed: product configuration should be equal:
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${key}'=='shipment' and '${value}' != '${EMPTY}'
+ ${shipment}= Set Variable ${shipment}
+ ELSE IF '${key}'=='shipment' and '${value}' == '${EMPTY}'
+ ${shipment}= Set Variable 1
+ END
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}'
+ ${sku}= Set Variable ${value}
+ END
+ IF '${key}'=='position' and '${value}' != '${EMPTY}'
+ ${position}= Set Variable ${value}
+ ELSE IF '${key}'=='position' and '${value}' == '${EMPTY}'
+ ${position}= Set Variable 1
+ END
+ IF '${key}'=='date' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[last()] ${value}
+ IF '${key}'=='date_time' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[3] ${value}
+ ELSE
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[4] ${value}
+ END
+ END
+ END
+
+Zed: new product configuration should be equal:
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${key}'=='shipment' and '${value}' != '${EMPTY}'
+ ${shipment}= Set Variable ${shipment}
+ ELSE IF '${key}'=='shipment' and '${value}' == '${EMPTY}'
+ ${shipment}= Set Variable 1
+ END
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}'
+ ${sku}= Set Variable ${value}
+ END
+ IF '${key}'=='position' and '${value}' != '${EMPTY}'
+ ${position}= Set Variable ${value}
+ ELSE IF '${key}'=='position' and '${value}' == '${EMPTY}'
+ ${position}= Set Variable 1
+ END
+ IF '${key}'=='Option One:' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[last()] ${value}
+ IF '${key}'=='Option Two:' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[3] ${value}
+ ELSE
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${position}]/td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td//*[contains(@class,'sku')]/../div[4] ${value}
+ END
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/customer_account_steps.robot b/atest/testdata/performance/resources/steps/customer_account_steps.robot
new file mode 100644
index 0000000..7da55b0
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/customer_account_steps.robot
@@ -0,0 +1,263 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_yves.robot
+Resource ../steps/header_steps.robot
+Resource ../steps/quick_order_steps.robot
+Resource ../pages/yves/yves_customer_account_page.robot
+Resource ../common/common_zed.robot
+Resource ../pages/zed/zed_customer_page.robot
+
+*** Keywords ***
+Yves: go to 'Customer Account' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/customer/overview
+
+Yves: go to user menu item in the left bar:
+ [Documentation] Case sensitive, accepts: Overview, Profile, Addresses, Order History, Newsletter, Shopping lists, Shopping carts, Quote Requests
+ [Arguments] ${left_navigation_node}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Run Keywords
+ Wait Until Element Is Visible xpath=//ul[@class='navigation-sidebar__list']//*[contains(.,'${left_navigation_node}')]/a
+ Click xpath=//ul[@class='navigation-sidebar__list']//*[contains(.,'${left_navigation_node}')]/a
+ ELSE IF '${env}'=='ui_suite'
+ Run Keywords
+ Wait Until Element Is Visible xpath=//nav[contains(@class,'customer-navigation')]//a[contains(text(),'${left_navigation_node}')]
+ Click xpath=//nav[contains(@class,'customer-navigation')]//a[contains(text(),'${left_navigation_node}')]
+ ELSE
+ Run Keywords
+ Wait Until Element Is Visible xpath=//a[contains(@class,'menu__link menu__link--customer-navigation') and contains(text(),'${left_navigation_node}')]
+ Click xpath=//a[contains(@class,'menu__link menu__link--customer-navigation') and contains(text(),'${left_navigation_node}')]
+ END
+
+Yves: create a new customer address in profile:
+ [Documentation]
+ [Arguments] ${salutation} ${firstName} ${lastName} ${street} ${houseNumber} ${postCode} ${city} ${country} ${isDefaultShipping}=True ${isDefaultBilling}=True ${company}= ${phone}= ${additionalAddress}=
+ Yves: remove flash messages
+ ${currentURL}= Get Location
+ IF 'customer/address' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}customer/address
+ ELSE
+ Go To ${yves_url}customer/address
+ END
+ END
+ Wait Until Element Is Visible ${customer_account_add_new_address_button}[${env}]
+ Click ${customer_account_add_new_address_button}[${env}]
+ Wait Until Element Is Visible ${customer_account_address_form}
+ Select From List By Value ${customer_account_address_salutation_select} ${salutation}
+ Type Text ${customer_account_address_first_name_field} ${firstName}
+ Type Text ${customer_account_address_last_name_field} ${lastName}
+ Type Text ${customer_account_address_company_name_field} ${company}
+ Type Text ${customer_account_address_street_field} ${street}
+ Type Text ${customer_account_address_house_number_field} ${houseNumber}
+ Type Text ${customer_account_address_additional_address_field} ${additionalAddress}
+ Type Text ${customer_account_address_zip_code_field} ${postCode}
+ Type Text ${customer_account_address_city_field} ${city}
+ Type Text ${customer_account_address_phone_field} ${phone}
+ Select From List By Text ${customer_account_address_country} ${country}
+ Click ${customer_account_address_submit_button}
+ Wait Until Element Is Visible ${customer_account_add_new_address_button}[${env}]
+
+Yves: create new default customer address in profile
+ [Arguments] ${salutation}=${default_address.salutation} ${firstName}=${default_address.first_name} ${lastName}=${default_address.last_name} ${street}=${default_address.street} ${houseNumber}=${default_address.house_number} ${postCode}=${default_address.post_code} ${city}=${default_address.city} ${country}=${default_address.country} ${isDefaultShipping}=True ${isDefaultBilling}=True ${company}=${EMPTY} ${phone}=${EMPTY} ${additionalAddress}=${EMPTY}
+ Yves: remove flash messages
+ ${currentURL}= Get Location
+ IF 'customer/address' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}customer/address
+ ELSE
+ Go To ${yves_url}customer/address
+ END
+ END
+ Wait Until Element Is Visible ${customer_account_add_new_address_button}[${env}]
+ Click ${customer_account_add_new_address_button}[${env}]
+ Wait Until Element Is Visible ${customer_account_address_form}
+ Select From List By Value ${customer_account_address_salutation_select} ${salutation}
+ Type Text ${customer_account_address_first_name_field} ${firstName}
+ Type Text ${customer_account_address_last_name_field} ${lastName}
+ Type Text ${customer_account_address_company_name_field} ${company}
+ Type Text ${customer_account_address_street_field} ${street}
+ Type Text ${customer_account_address_house_number_field} ${houseNumber}
+ Type Text ${customer_account_address_additional_address_field} ${additionalAddress}
+ Type Text ${customer_account_address_zip_code_field} ${postCode}
+ Type Text ${customer_account_address_city_field} ${city}
+ Type Text ${customer_account_address_phone_field} ${phone}
+ Select From List By Text ${customer_account_address_country} ${country}
+ Click ${customer_account_address_submit_button}
+ Wait Until Element Is Visible ${customer_account_add_new_address_button}[${env}]
+
+Yves: check that user has address exists/doesn't exist:
+ Yves: remove flash messages
+ [Arguments] ${exists} ${firstName} ${lastName} ${street} ${houseNumber} ${postCode} ${city} ${country} ${isDefaultShipping}=True ${isDefaultBilling}=True ${company}=NUll ${phone}=NUll ${additionalAddress}=NUll
+ ${exists}= Convert To Lower Case ${exists}
+ ${currentURL}= Get Location
+ IF 'customer/address' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}customer/address
+ ELSE
+ Go To ${yves_url}customer/address
+ END
+ END
+ Wait Until Element Is Visible ${customer_account_add_new_address_button}[${env}]
+ IF '${exists}'=='true'
+ Run keywords
+ Element Should Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${firstName} ${lastName}')]
+ Element Should Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${street} ${houseNumber}')]
+ Element Should Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${postCode} ${city}, ${country}')]
+ ELSE
+ Run keywords
+ Element Should Not Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${firstName} ${lastName}')]
+ Element Should Not Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${street} ${houseNumber}')]
+ Element Should Not Be Visible xpath=//ul[contains(@class,'display-address')]//*[contains(text(),'${postCode} ${city}, ${country}')]
+ END
+
+Yves: delete user address:
+ [Arguments] ${street}
+ Yves: remove flash messages
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Yves: go to user menu: My Profile
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Yves: go to user menu: Profile
+ END
+ Yves: go to user menu item in the left bar: Addresses
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Click xpath=//li[contains(text(),'${street}')]/ancestor::div/div[@data-qa='component title-box']//form[contains(@action,'address/delete')]//button
+ Page Should Not Contain Element xpath=//li[contains(text(),'${street}')]/ancestor::div/div[@data-qa='component title-box']//form[contains(@action,'address/delete')]//button
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Click xpath=//li[contains(text(),'${street}')]/ancestor::div[@data-qa="component action-card"]//form[contains(@action,'address/delete')]//button
+ Page Should Not Contain Element xpath=//li[contains(text(),'${street}')]/ancestor::div[@data-qa="component action-card"]//form[contains(@action,'address/delete')]//button
+ ELSE
+ Click xpath=//li[contains(text(),'${street}')]/ancestor::div[1]//form[contains(@action,'delete')]//button
+ Page Should Not Contain Element xpath=//li[contains(text(),'${street}')]/ancestor::div[1]//form[contains(@action,'delete')]//button
+ END
+
+Yves: delete all user addresses
+ ${currentURL}= Get Location
+ IF '/customer/address' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}customer/address
+ ELSE
+ Go To ${yves_url}customer/address
+ END
+ END
+ ${userAddresses}= Get Element Count xpath=//form[contains(@action,'address/delete')]//button
+ IF ${userAddresses} != 0
+ FOR ${index} IN RANGE 0 ${userAddresses}
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Click xpath=//main//div[contains(@class,'col--md')]/div[contains(@class,'grid')]/div[1]//div[@data-qa='component title-box']//form[contains(@action,'address/delete')]//button
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Click xpath=//div[@data-qa='component action-card-grid']/div[1]/div[@data-qa="component action-card"]//form[contains(@action,'address/delete')]//button
+ ELSE
+ Click xpath=(//div//form[contains(@action,'delete')]//button)[1]
+ END
+ END
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: assert customer profile data:
+ [Arguments] @{args}
+ Wait Until Element Is Visible ${customer_account_profile_first_name_field}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Get Text ${customer_account_profile_salutation_span}[${env}] contains ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Get Text ${customer_account_profile_first_name_field} contains ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Get Text ${customer_account_profile_last_name_field} contains ${value}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Get Text ${customer_account_profile_email_field} contains ${value}
+ END
+
+Yves: update customer profile data:
+ [Arguments] @{args}
+ Wait Until Element Is Visible ${customer_account_profile_first_name_field}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}'
+ IF '${env}' in ['ui_suite']
+ Select From List By Label ${customer_account_profile_salutation_selector} ${value}
+ ELSE
+ Click ${customer_account_profile_salutation_span}[${env}]
+ Click xpath=//li[contains(@id,'select2-profileForm_salutation-result')][contains(text(),'${value}')]
+ END
+ END
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${customer_account_profile_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${customer_account_profile_last_name_field} ${value}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${customer_account_profile_email_field} ${value}
+ END
+ Click ${customer_account_profile_submit_profile_button}
+
+Zed: assert customer profile data:
+ [Arguments] @{args}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /customer
+ Zed: click Action Button in a table for row that contains: ${email} Edit
+ Wait Until Element Is Visible ${zed_customer_edit_salutation_select}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Get Text xpath=//select[@id='customer_salutation']//option[@selected] contains ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Get Text ${zed_customer_edit_first_name_field} contains ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Get Text ${zed_customer_edit_last_name_field} contains ${value}
+ END
+ Zed: submit the form
+
+Zed: update customer profile data:
+ [Arguments] @{args}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /customer
+ Zed: click Action Button in a table for row that contains: ${email} Edit
+ Wait Until Element Is Visible ${zed_customer_edit_salutation_select}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${zed_customer_edit_salutation_select} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_last_name_field} ${value}
+ END
+ Zed: submit the form
+
+Zed: create a new customer address in profile:
+ [Arguments] @{args}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /customer
+ Zed: click Action Button in a table for row that contains: ${email} View
+ Zed: click button in Header: Add new Address
+ Wait Until Element Is Visible ${zed_customer_edit_address_salutation_select}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${zed_customer_edit_address_salutation_select} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_last_name_field} ${value}
+ IF '${key}'=='address 1' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_address_1_field} ${value}
+ IF '${key}'=='address 2' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_address_2_field} ${value}
+ IF '${key}'=='address 3' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_address_3_field} ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_city_field} ${value}
+ IF '${key}'=='zip code' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_zip_code_field} ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label ${zed_customer_edit_address_country_select} ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_phone_field} ${value}
+ IF '${key}'=='company' and '${value}' != '${EMPTY}' Type Text ${zed_customer_edit_address_company_field} ${value}
+ END
+ Click ${zed_customer_edit_address_submit_button}
+ ${error_flash_message}= Run Keyword And Ignore Error Page Should Not Contain Element ${zed_error_flash_message} 400ms
+ IF 'FAIL' in $error_flash_message
+ Click ${zed_customer_edit_address_submit_button}
+ END
+ ${error_message}= Run Keyword And Ignore Error Page Should Not Contain Element ${zed_error_message} 400ms
+ IF 'FAIL' in $error_message
+ Click ${zed_customer_edit_address_submit_button}
+ END
+ Wait Until Element Is Not Visible ${zed_customer_edit_address_submit_button}
+
+Yves: go to user menu:
+ [Arguments] ${user_menu_item}
+ ${user_menu_item}= Convert To Lower Case ${user_menu_item}
+ IF 'profile' in '${user_menu_item}' Yves: go to URL: /customer/profile
+ IF 'sign' in '${user_menu_item}' Yves: go to URL: /register
+ IF 'login' in '${user_menu_item}' Yves: go to URL: /login
+ IF 'history' in '${user_menu_item}' or 'order' in '${user_menu_item}' Yves: go to URL: /customer/order
+ IF 'overview' in '${user_menu_item}' Yves: go to URL: /customer/overview
+ IF 'quote' in '${user_menu_item}' Yves: go to URL: /quote-request
+ IF 'address' in '${user_menu_item}' Yves: go to URL: /customer/address
+ IF 'return' in '${user_menu_item}' Yves: go to URL: /return/list
+ IF 'newsletter' in '${user_menu_item}' Yves: go to URL: /customer/newsletter
+ IF 'shopping list' in '${user_menu_item}' or 'shopping-list' in '${user_menu_item}' Yves: go to URL: /shopping-list
+ IF 'cart' in '${user_menu_item}' Yves: go to URL: /multi-cart
+ IF 'wishlist' in '${user_menu_item}' Yves: go to URL: /wishlist
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/customer_registration_steps.robot b/atest/testdata/performance/resources/steps/customer_registration_steps.robot
new file mode 100644
index 0000000..3a006e6
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/customer_registration_steps.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../steps/quick_order_steps.robot
+Resource ../pages/yves/yves_customer_account_page.robot
+Resource ../../resources/common/common.robot
+Resource ../pages/yves/yves_customer_registration_page.robot
+Resource ../steps/customer_account_steps.robot
+
+*** Keywords ***
+Register a new customer with data:
+ [Documentation] Possible argument names: e-mail, salutation, first name, last name, password
+ [Arguments] @{args}
+ ${registrationData}= Set Up Keyword Arguments @{args}
+ Yves: go to user menu: Sign Up
+ FOR ${key} ${value} IN &{registrationData}
+ IF '${key}'=='first name' Type Text ${registration_first_name_field} ${value}
+ IF '${key}'=='last name' Type Text ${registration_last_name_field} ${value}
+ IF '${key}'=='e-mail' Type Text ${registration_email_field} ${value}
+ IF '${key}'=='password' Run keywords
+ Type Text ${registration_password_field} ${value}
+ Type Text ${registration_password_confirmation_field} ${value}
+# Run keyword if '${key}'=='salutation' Type Text ${checkout_shipping_address_company_name_field} ${company}
+ END
+ Click Element by id with JavaScript registerForm_accept_terms
+ Click ${registration_submit_button}
diff --git a/atest/testdata/performance/resources/steps/dynamic_entity_steps.robot b/atest/testdata/performance/resources/steps/dynamic_entity_steps.robot
new file mode 100644
index 0000000..40d4b8b
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/dynamic_entity_steps.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Resource ../common/common_api.robot
+Resource ../common/common_zed.robot
+Resource ../../resources/pages/zed/zed_data_exchange_api_configurator_page.robot
+
+
+*** Keywords ***
+Zed: start creation of new data exchange api configuration for db table:
+ [Arguments] ${table_name}
+ Zed: go to URL: /dynamic-entity-gui/configuration-list
+ Zed: perform search by: ${table_name}
+ ${is_table_empty}= Run Keyword And Ignore Error Page Should Contain Element xpath=//table//td[contains(@class,'empty')] timeout=400ms
+ IF 'PASS' in $is_table_empty
+ Zed: click button in Header: Data Exchange API Configuration
+ Select From List By Value ${data_exchange_table_select_locator} ${table_name}
+ Click ${data_exchange_create_configuration_button}
+ Wait Until Page Contains Element ${data_exchange_resource_name_field}
+ ELSE
+ Zed: click Action Button in a table for row that contains: ${table_name} Edit
+ Wait Until Page Contains Element ${data_exchange_resource_name_field}
+ END
+
+Zed: edit data exchange api configuration:
+ [Arguments] @{args}
+ ${configurationData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{configurationData}
+ IF '${key}'=='table_name' and '${value}' != '${EMPTY}'
+ ${currentURL}= Get Location
+ IF '/configuration-list' not in '${currentURL}' Zed: go to URL: /dynamic-entity-gui/configuration-list
+ Zed: click Action Button in a table for row that contains: ${value} Edit
+ Wait Until Page Contains Element ${data_exchange_resource_name_field}
+ END
+ IF '${key}'=='is_enabled' and '${value}' == 'true' Zed: Check checkbox by Label: Is enabled
+ IF '${key}'=='is_enabled' and '${value}' == 'false' Zed: Uncheck Checkbox by Label: Is enabled
+ IF '${key}'=='is_deletable' and '${value}' == 'true' Zed: Check checkbox by Label: Is deletable
+ IF '${key}'=='is_deletable' and '${value}' == 'false' Zed: Uncheck Checkbox by Label: Is deletable
+ IF '${key}'=='field_name' and '${value}' != '${EMPTY}'
+ ${field_name}= Set Variable ${value}
+ END
+ IF '${key}'=='enabled' and '${value}' == 'true' Check Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'is_enabled')]
+ IF '${key}'=='enabled' and '${value}' == 'false' Uncheck Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'is_enabled')]
+ IF '${key}'=='visible_name' and '${value}' != '${EMPTY}' Type Text xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'visible_name')] ${value}
+ IF '${key}'=='type' and '${value}' != '${EMPTY}' Select From List By Value xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//select[contains(@name,'type')] ${value}
+ IF '${key}'=='creatable' and '${value}' == 'true' Check Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'creatable')]
+ IF '${key}'=='creatable' and '${value}' == 'false' Uncheck Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'creatable')]
+ IF '${key}'=='editable' and '${value}' == 'true' Check Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'editable')]
+ IF '${key}'=='editable' and '${value}' == 'false' Uncheck Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'editable')]
+ IF '${key}'=='required' and '${value}' == 'true' Check Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'required')]
+ IF '${key}'=='required' and '${value}' == 'false' Uncheck Checkbox xpath=//input[contains(@id,'dynamic-entity_field_definitions')][@value='${field_name}']/ancestor::tr//input[contains(@name,'required')]
+ END
+
+Zed: save data exchange api configuration
+ Click ${data_exchange_create_configuration_button}
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Page Should Not Contain Element ${zed_error_message} 1s
+ Page Should Not Contain Element ${zed_error_flash_message} 1s
+
+Zed: download data exchange api specification should be active:
+ [Arguments] ${expected_condition}
+ ${currentURL}= Get Location
+ IF '/configuration-list' not in '${currentURL}' Zed: go to URL: /dynamic-entity-gui/configuration-list
+ ${expected_condition}= Convert To Lower Case ${expected_condition}
+ IF '${expected_condition}' == 'true'
+ Wait Until Element Is Enabled ${data_exchange_download_spec_button} timeout=3s message=Data Exchange API spec is NOT downloadable
+ ELSE
+ ${download_button_state}= Get Element Attribute ${data_exchange_download_spec_button} class
+ Should Contain ${download_button_state} disabled message=Data Exchange API spec is downloadable BUT should NOT
+ END
+
+Zed: download data exchange api specification
+ [Documentation] Downloads BAPI spec file and returns file location (path) in '${specification_file_path}' variable
+ ${dl_promise} Promise To Wait For Download saveAs=${OUTPUTDIR}/tmp.file
+ Click ${data_exchange_download_spec_button}
+ ${status} ${file_object}= Run Keyword And Ignore Error Wait For ${dl_promise}
+ File Should Exist ${file_object}[saveAs]
+ Move File ${file_object}[saveAs] ${OUTPUTDIR}/${file_object.suggestedFilename}
+ Should Be Equal ${file_object.suggestedFilename} schema.yml
+ Set Test Variable ${specification_file_path} ${OUTPUTDIR}/${file_object.suggestedFilename}
+
+Zed: check that downloaded api specification contains:
+ [Arguments] ${expected_content}
+ ${file_content}= Get File ${specification_file_path}
+ Should Contain ${file_content} ${expected_content}
+
+Zed: check that downloaded api specification does not contain:
+ [Arguments] ${expected_content}
+ ${file_content}= Get File ${specification_file_path}
+ Should Not Contain ${file_content} ${expected_content}
+
+Zed: delete downloaded api specification
+ Remove File ${specification_file_path}
+
+Zed: wait until info box is not displayed
+ [Arguments] ${iterations}=20 ${delays}=10
+ Try reloading page until element is/not appear: ${zed_info_flash_message} false tries=${iterations} timeout=${delays} message='Download API Specification' button is disabled. Check "Trigger API specification update" CLI command results
diff --git a/atest/testdata/performance/resources/steps/glossary_steps.robot b/atest/testdata/performance/resources/steps/glossary_steps.robot
new file mode 100644
index 0000000..3222d8d
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/glossary_steps.robot
@@ -0,0 +1,35 @@
+*** Settings ***
+Resource ../pages/zed/zed_customer_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_glossary_page.robot
+
+*** Keywords ***
+Zed: fill glossary form:
+ [Documentation] fill the input fields required for creating translation.
+ [Arguments] @{args}
+ ${registrationData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{registrationData}
+ IF '${key}'=='Name' and '${value}' != '${EMPTY}' Type Text ${zed_translation_name} ${value}
+ IF '${key}'=='EN_US' and '${value}' != '${EMPTY}' Type Text ${zed_translation_EN_US} ${value}
+ IF '${key}'=='DE_DE' and '${value}' != '${EMPTY}' Type Text ${zed_translation_DE_DE} ${value}
+ END
+
+Zed: undo the changes in glossary translation:
+ [Arguments] ${glossaryName} ${original_DE} ${original_EN} ${admin_email}=${zed_admin_email}
+ ${currentURL}= Get Location
+ ${dynamic_admin_user_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ IF ${dynamic_admin_user_exists} and '${admin_email}' == '${zed_admin_email}'
+ VAR ${admin_email} ${dynamic_admin_user}
+ ELSE IF not ${dynamic_admin_user_exists}
+ VAR ${admin_email} ${zed_admin_email}
+ END
+ IF '${zed_url}' not in '${currentURL}' or '${zed_url}security-gui/login' in '${currentURL}'
+ Zed: login on Zed with provided credentials: ${admin_email}
+ END
+ Zed: go to URL: /glossary
+ Zed: click Action Button in a table for row that contains: ${glossaryName} Edit
+ Zed: fill glossary form:
+ ... || DE_DE | EN_US ||
+ ... || ${original_DE} | ${original_EN} ||
+ Zed: submit the form
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/header_steps.robot b/atest/testdata/performance/resources/steps/header_steps.robot
new file mode 100644
index 0000000..0523980
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/header_steps.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../pages/yves/yves_header_section.robot
+Resource ../pages/yves/yves_catalog_page.robot
+Resource ../steps/request_for_quote_steps.robot
+Resource ../steps/shopping_carts_steps.robot
+Resource ../steps/shopping_lists_steps.robot
+Resource ../steps/quick_order_steps.robot
+Resource ../steps/request_for_quote_steps.robot
+Resource ../steps/wishlist_steps.robot
+
+*** Variables ***
+${priceModeSwitcher} ${price_mode_switcher_header_menu_item}
+${currencySwitcher} ${currency_switcher_header_menu_item}
+${languageSwitcher} ${language_switcher_header_menu_item}
+${quickOrderIcon} ${quick_order_icon_header_menu_item}
+${accountIcon} ${user_navigation_icon_header_menu_item}[${env}]
+${shoppingListIcon} ${shopping_list_icon_header_menu_item}[${env}]
+${shoppingCartIcon} ${shopping_car_icon_header_menu_item}[${env}]
+${customerSearchWidget} ${agent_customer_search_widget}
+${quoteRequestsWidget} ${agent_quote_requests_header_item}
+${wishlistIcon} ${wishlist_icon_header_navigation_widget}
+
+*** Keywords ***
+Yves: perform search by:
+ [Arguments] ${searchTerm}
+ IF '${env}' in ['ui_b2c','ui_mp_b2c']
+ Run Keywords
+ Wait Until Page Contains Element ${search_form_open_menu_item}
+ Click ${search_form_open_menu_item}
+ END
+ Wait Until Page Contains Element ${search_form_header_menu_item}
+ Type Text ${search_form_header_menu_item} ${searchTerm}
+ Keyboard Key press Enter
+ Wait Until Page Contains Element ${catalog_main_page_locator}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: go to company menu item:
+ [Arguments] ${company_menu_item}
+ wait until element is visible ${company_name_icon_header_menu_item}
+ mouse over ${company_name_icon_header_menu_item}
+ Click //div[@class='header__top']//a[contains(@class,'navigation-top__company')]/..//nav[contains(@class,'navigation-list')]/ul//a[text()='${company_menu_item}']
+
+
+Yves: company menu '${condition}' be available for logged in user
+ IF '${condition}' == 'should' Run Keywords
+ ... wait until element is visible ${company_name_icon_header_menu_item}
+ ... AND mouse over ${company_name_icon_header_menu_item}
+ ... ELSE Page Should Not Contain Element ${company_name_icon_header_menu_item}
+
+Yves: header contains/doesn't contain:
+ [Arguments] ${condition} @{header_elements_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${condition}= Convert To Lower Case ${condition}
+ ${header_elements_list_count}= get length ${header_elements_list}
+ FOR ${index} IN RANGE 0 ${header_elements_list_count}
+ ${header_element_to_check}= Get From List ${header_elements_list} ${index}
+ IF '${condition}' == 'true'
+ Run Keywords
+ Log ${header_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Contain Element ${header_element_to_check} message=${header_element_to_check} is not displayed
+ END
+ IF '${condition}' == 'false'
+ Run Keywords
+ Log ${header_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Not Contain Element ${header_element_to_check} message=${header_element_to_check} should not be displayed
+ END
+ END
+
+Yves: go to '${pageName}' page through the header
+ IF '${pageName}' == 'Shopping Lists'
+ Yves: go to 'Shopping Lists' page
+ ELSE IF '${pageName}' == 'Shopping Carts'
+ Yves: go to 'Shopping Carts' page
+ ELSE IF '${pageName}' == 'Quick Order'
+ Yves: go to 'Quick Order' page
+ ELSE IF '${pageName}' == 'Quote Requests'
+ Yves: go to 'Agent Quote Requests' page
+ ELSE IF '${pageName}' == 'Wishlist'
+ Yves: go to 'Wishlist' page
+ ELSE IF '${pageName}' == 'Agent Quote Requests'
+ Yves: go to 'Agent Quote Requests' page
+ END
+
+Yves: go to user menu item in header:
+ [Arguments] ${user_menu_item}
+ Wait Until Element Is Visible ${user_navigation_icon_header_menu_item}[${env}]
+ Mouse Over ${user_navigation_icon_header_menu_item}[${env}]
+ Wait Until Element Is Visible ${user_navigation_fly_out_header_menu_item}[${env}]
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Click xpath=//li[contains(@class,'user-navigation__item--user')]//nav[contains(@class,'user-navigation__sub-nav')]//ul[contains(@class,'list--secondary')]//a[text()='${user_menu_item}']
+ ELSE
+ Click xpath=//a[contains(@class,'user-block') and contains(text(),'${user_menu_item}')]
+ END
+
+Yves: move mouse over header menu item:
+ [Arguments] @{header_elements_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${header_elements_list_count}= get length ${header_elements_list}
+ FOR ${index} IN RANGE 0 ${header_elements_list_count}
+ ${header_element_to_check}= Get From List ${header_elements_list} ${index}
+ Mouse Over ${header_element_to_check}
+ Sleep 1s
+ END
+
+Yves: '${headerItem}' widget is shown
+ IF '${headerItem}' == 'Quote Requests'
+ Run Keywords
+ Wait Until Element Is Visible ${agent_quote_requests_widget}
+ Page Should Contain Element ${agent_quote_requests_widget}
+ END
diff --git a/atest/testdata/performance/resources/steps/merchant_profile_steps.robot b/atest/testdata/performance/resources/steps/merchant_profile_steps.robot
new file mode 100644
index 0000000..cc8653e
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/merchant_profile_steps.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../common/common_ui.robot
+Resource ../pages/yves/yves_merchant_profile.robot
+Resource ../pages/yves/yves_header_section.robot
+
+*** Variables ***
+
+*** Keywords ***
+Yves: assert merchant profile fields:
+ [Arguments] @{args}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${merchant_profile_main_content_locator}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Run Keywords
+ ... Try reloading page until element does/not contain text: ${merchant_profile_email_locator} ${value} true 26 5s
+ ... AND Element Text Should Be ${merchant_profile_email_locator} ${value}
+ IF '${key}'=='name' and '${value}' != '${EMPTY}' Run Keywords
+ ... Try reloading page until element does/not contain text: ${merchant_profile_name_header_locator}[${env}] ${value} true 26 5s
+ ... AND Element Text Should Be ${merchant_profile_name_header_locator}[${env}] ${value}
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Element Text Should Be ${merchant_profile_phone_locator} ${value}
+ IF '${key}'=='delivery time' and '${value}' != '${EMPTY}' Element Text Should Be ${merchant_profile_delivery_time_locator} ${value}
+ IF '${key}'=='data privacy' and '${value}' != '${EMPTY}' Element Text Should Be ${merchant_profile_data_privacy_locator} ${value}
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/merchants_steps.robot b/atest/testdata/performance/resources/steps/merchants_steps.robot
new file mode 100644
index 0000000..4d49dff
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/merchants_steps.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Resource ../common/common_ui.robot
+Resource ../common/common_zed.robot
+Resource product_set_steps.robot
+Resource ../pages/zed/zed_product_list_page.robot
+
+*** Keywords ***
+Zed: assign product list to merchant relation:
+ [Arguments] ${business_unit_owner} ${merchant_relation} ${product_list}
+ ${currentURL}= Get Url
+ IF '/list-merchant-relationship' not in '${currentURL}' Go To ${zed_url}merchant-relationship-gui/list-merchant-relationship
+ Zed: perform search by: ${business_unit_owner}
+ Zed: click Action Button(without search) in a table for row that contains: ${merchant_relation} Edit
+ ${is_list_already_selected}= Run Keyword And Ignore Error Page Should Contain Element xpath=//*[@id='merchant-relationship_productListIds']//option[contains(.,'${product_list}')][@selected] timeout=0.5s
+ IF 'FAIL' in $is_list_already_selected
+ Type Text xpath=//select[@id="merchant-relationship_productListIds"]/following-sibling::*//input[contains(@class,'select2-search')] ${product_list} delay=50ms
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${product_list}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${product_list}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${product_list}')]
+ Sleep 1s
+ Zed: submit the form
+ END
+
+Zed: unassign all product lists from merchant relation:
+ [Arguments] ${business_unit_owner} ${merchant_relation}
+ ${currentURL}= Get Url
+ IF '/list-merchant-relationship' not in '${currentURL}' Go To ${zed_url}merchant-relationship-gui/list-merchant-relationship
+ Zed: perform search by: ${business_unit_owner}
+ Zed: click Action Button(without search) in a table for row that contains: ${merchant_relation} Edit
+ ${are_lists_already_selected}= Run Keyword And Ignore Error Page Should Contain Element xpath=(//select[@id="merchant-relationship_productListIds"]/following-sibling::*//*[contains(@class,'remove')][contains(@class,'choice')])[1] timeout=0.5s
+ IF 'PASS' in $are_lists_already_selected
+ ${iterations}= Get Element Count xpath=//select[@id="merchant-relationship_productListIds"]/following-sibling::*//*[contains(@class,'remove')][contains(@class,'choice')]
+ FOR ${index} IN RANGE 1 ${iterations}+1
+ Click xpath=(//select[@id="merchant-relationship_productListIds"]/following-sibling::*//*[contains(@class,'remove')][contains(@class,'choice')])[${index}]
+ Wait Until Element Is Not Visible xpath=(//select[@id="merchant-relationship_productListIds"]/following-sibling::*//*[contains(@class,'remove')][contains(@class,'choice')])[${index}]
+ Click xpath=//select[@id="merchant-relationship_productListIds"]/following-sibling::*//input[contains(@class,'select2-search')]
+ END
+ Sleep 1s
+ Zed: submit the form
+ END
+
+
+Zed: create product list with the following assigned category:
+ [Arguments] ${list_name} ${list_type} ${category}
+ Go To ${zed_url}product-list-gui/create
+ Wait Until Element Is Visible ${zed_product_list_title_field}
+ Type Text ${zed_product_list_title_field} ${list_name}
+ ${list_type}= Convert To Lower Case ${list_type}
+ IF '${list_type}' == 'whitelist' or '${list_type}' == 'white' Click ${zed_product_list_type_whitelist_radio}
+ IF '${list_type}' == 'blacklist' or '${list_type}' == 'black' Click ${zed_product_list_type_blacklist_radio}
+ Zed: switch to tab in product list: Assign Categories
+ Wait Until Page Contains Element ${zed_product_list_categories_search_field}
+ Type Text ${zed_product_list_categories_search_field} ${category}
+ Wait Until Element Is Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${category}')]
+ Click xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${category}')]
+ Wait Until Element Is Not Visible xpath=//*[contains(@class,'select2-results')][contains(@class,'options')]//li[contains(text(),'${category}')]
+ Zed: submit the form
+
+Zed: switch to tab in product list:
+ [Arguments] ${tab_name}
+ Click xpath=//form[@name='productListAggregate']//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-tab-content-id]//a[contains(.,'${tab_name}')]
+
+Zed: remove product list with title:
+ [Arguments] ${product_list_title}
+ Go To ${zed_url}product-list-gui
+ Zed: perform search by: ${product_list_title}
+ ${is_product_list_exists}= Run Keyword And Ignore Error Zed: table should contain non-searchable value: ${product_list_title}
+ IF 'PASS' in $is_product_list_exists
+ Zed: click Action Button(without search) in a table for row that contains: ${product_list_title} Remove List
+ Wait Until Element Is Visible ${zed_product_list_confirm_removal_button}
+ Click ${zed_product_list_confirm_removal_button}
+ END
diff --git a/atest/testdata/performance/resources/steps/minimum_order_value_steps.robot b/atest/testdata/performance/resources/steps/minimum_order_value_steps.robot
new file mode 100644
index 0000000..92fbb52
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/minimum_order_value_steps.robot
@@ -0,0 +1,102 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_zed.robot
+Resource ../../resources/pages/zed/zed_edit_global_threshold_page.robot
+Resource ../../resources/pages/yves/yves_shopping_cart_page.robot
+Resource ../../resources/pages/yves/yves_checkout_summary_page.robot
+Resource ../common/common_yves.robot
+Resource ../../resources/steps/checkout_steps.robot
+
+
+*** Keywords ***
+Zed: change global threshold settings:
+ [Arguments] @{args}
+ ${thresholdData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /sales-order-threshold-gui/global
+ Wait Until Element Is Visible ${zed_global_threshold_store_currency_span}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ FOR ${key} ${value} IN &{thresholdData}
+ IF '${key}'=='store & currency' and '${value}' != '${EMPTY}'
+ Select From List By Label ${zed_global_threshold_store_currency_select} ${value}
+ ${second_local_minimum_hard_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_minimum_hard_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_minimum_hard_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_minimum_hard_second_locale_collapce_section}
+ Click ${zed_global_threshold_minimum_hard_second_locale_collapce_section}
+ END
+ ${second_local_maximum_hard_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_maximum_hard_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_maximum_hard_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_maximum_hard_second_locale_collapce_section}
+ Click ${zed_global_threshold_maximum_hard_second_locale_collapce_section}
+ END
+ ${second_local_soft_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_soft_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_soft_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_soft_second_locale_collapce_section}
+ Click ${zed_global_threshold_soft_second_locale_collapce_section}
+ END
+ END
+ IF '${key}'=='store & currency' and '${value}' == '${EMPTY}'
+ ${second_local_minimum_hard_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_minimum_hard_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_minimum_hard_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_minimum_hard_second_locale_collapce_section}
+ Click ${zed_global_threshold_minimum_hard_second_locale_collapce_section}
+ END
+ ${second_local_maximum_hard_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_maximum_hard_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_maximum_hard_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_maximum_hard_second_locale_collapce_section}
+ Click ${zed_global_threshold_maximum_hard_second_locale_collapce_section}
+ END
+ ${second_local_soft_section_expanded}= Run Keyword And Return Status Page Should Not Contain Element ${zed_global_threshold_soft_second_locale_collapce_section} timeout=500ms
+ IF '${second_local_soft_section_expanded}'=='False'
+ Scroll Element Into View ${zed_global_threshold_soft_second_locale_collapce_section}
+ Click ${zed_global_threshold_soft_second_locale_collapce_section}
+ END
+ END
+ IF '${key}'=='minimum hard value' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_minimum_hard_value_input} ${value}
+ IF '${key}'=='minimum hard en message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_minimum_hard_en_message_input} ${value}
+ IF '${key}'=='minimum hard de message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_minimum_hard_de_message_input} ${value}
+ IF '${key}'=='maximum hard value' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_maximum_hard_value_input} ${value}
+ IF '${key}'=='maximum hard en message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_maximum_hard_en_message_input} ${value}
+ IF '${key}'=='maximum hard de message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_maximum_hard_de_message_input} ${value}
+ IF '${key}'=='soft threshold' and '${value}' != '${EMPTY}' Click xpath=//input[contains(@name,'global-threshold[softThreshold][strategy]')]/../../label[contains(.,'${value}')]
+ IF '${key}'=='soft threshold value' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_soft_value_input} ${value}
+ IF '${key}'=='soft threshold en message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_soft_en_message_input} ${value}
+ IF '${key}'=='soft threshold de message' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_soft_de_message_input} ${value}
+ IF '${key}'=='soft threshold fixed fee' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_soft_fixed_fee_value_input} ${value}
+ IF '${key}'=='soft threshold flexible fee' and '${value}' != '${EMPTY}' Type Text ${zed_global_threshold_soft_flexible_fee_value_input} ${value}
+ END
+ Zed: submit the form
+ Zed: flash message should be shown: success
+
+Yves: soft threshold surcharge is added in the cart:
+ [Arguments] ${expectedSurchargeAmount}
+ Wait Until Element Is Visible ${shopping_cart_surcharge_amount}[${env}]
+ Scroll Element Into View ${shopping_cart_surcharge_amount}[${env}]
+ ${actualSurchargeAmount}= Get Text ${shopping_cart_surcharge_amount}[${env}]
+ Should Be Equal ${actualSurchargeAmount} ${expectedSurchargeAmount}
+
+Yves: soft threshold surcharge is added on summary page:
+ [Arguments] ${expectedSurchargeAmount}
+ Wait Until Element Is Visible ${checkout_summary_surcharge_amount}[${env}]
+ Scroll Element Into View ${checkout_summary_surcharge_amount}[${env}]
+ ${actualSurchargeAmount}= Get Text ${checkout_summary_surcharge_amount}[${env}]
+ Should Be Equal ${actualSurchargeAmount} ${expectedSurchargeAmount}
+
+Yves: hard threshold is applied with the following message:
+ [Arguments] ${expectedMessage}
+ TRY
+ Element Should Be Visible ${checkout_summary_alert_message}[${env}]
+ Page Should Not Contain Element ${checkout_summary_submit_order_button}
+ ${actualAlertMessage}= Get Text ${checkout_summary_alert_message}[${env}]
+ Should Contain ${actualAlertMessage} ${expectedMessage}
+ EXCEPT
+ Yves: accept the terms and conditions: true
+ Click ${checkout_summary_submit_order_button}
+ Yves: flash message should be shown: error ${expectedMessage}
+ END
+
+
diff --git a/atest/testdata/performance/resources/steps/mp_account_steps.robot b/atest/testdata/performance/resources/steps/mp_account_steps.robot
new file mode 100644
index 0000000..3c35461
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_account_steps.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../pages/mp/mp_account_page.robot
+Resource ../common/common_yves.robot
+
+*** Keywords ***
+MP: update merchant personal details with data:
+ [Arguments] @{args}
+ Click ${mp_user_menu_button}
+ Wait Until Element Is Visible ${mp_my_account_header_menu_item}
+ Click ${mp_my_account_header_menu_item}
+ ${personalData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${mp_account_first_name_field}
+ FOR ${key} ${value} IN &{personalData}
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text ${mp_account_first_name_field} ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text ${mp_account_last_name_field} ${value}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${mp_account_email_field} ${value}
+ IF '${key}'=='currentPassword' and '${value}' != '${EMPTY}' Set Test Variable ${currentPassword} ${value}
+ IF '${key}'=='newPassword' and '${value}' != '${EMPTY}'
+ Click ${mp_account_change_password_button}
+ Wait Until Page Contains Element ${mp_account_current_password_field}
+ Wait Until Element Is Visible ${mp_account_current_password_field}
+ Type Text ${mp_account_current_password_field} ${currentPassword}
+ Type Text ${mp_account_new_password_field} ${value}
+ Type Text ${mp_account_repeat_new_password_field} ${value}
+ Click ${mp_account_save_password_button}
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/mp_dashboard_steps.robot b/atest/testdata/performance/resources/steps/mp_dashboard_steps.robot
new file mode 100644
index 0000000..70f9f66
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_dashboard_steps.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../../resources/pages/mp/mp_dashboard_page.robot
+
+*** Keywords ***
+MP: click button on dashboard page and check url:
+ [Arguments] ${button_name} ${expected_rel_url}
+ ${currentURL}= Get Location
+ IF 'dashboard' not in '${currentURL}' MP: open navigation menu tab: Dashboard
+ ${button_name}= Convert To Lower Case ${button_name}
+ IF '${button_name}' == 'manage offers'
+ Click ${mp_dashboard_manage_offers_button}
+ ${location}= Get Url
+ Should Contain ${location} ${expected_rel_url}
+ ELSE IF '${button_name}' == 'add offer'
+ Click ${mp_dashboard_add_offer_button}
+ ${location}= Get Url
+ Should Contain ${location} ${expected_rel_url}
+ ELSE IF '${button_name}' == 'manage orders'
+ Click ${mp_dashboard_manage_orders_button}
+ ${location}= Get Url
+ Should Contain ${location} ${expected_rel_url}
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/mp_offers_steps.robot b/atest/testdata/performance/resources/steps/mp_offers_steps.robot
new file mode 100644
index 0000000..b1f1cad
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_offers_steps.robot
@@ -0,0 +1,197 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../pages/mp/mp_offer_drawer.robot
+Resource ../pages/mp/mp_product_drawer.robot
+Resource ../pages/zed/zed_view_offer_page.robot
+
+*** Keywords ***
+MP: fill offer fields:
+ [Arguments] @{args}
+ ${productData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${offer_active_checkbox}
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='is active' and '${value}' != '${EMPTY}'
+ ${checkbox_state}= Get Element Attribute xpath=//web-spy-checkbox[@spy-id='productOffer_isActive']//span[@class='ant-checkbox-inner']/../../span[contains(@class,'checkbox')] class
+ IF 'checked' in '${checkbox_state}' and '${value}' == 'false'
+ Click ${offer_active_checkbox}
+ ELSE IF 'checked' not in '${checkbox_state}' and '${value}' == 'true'
+ Click ${offer_active_checkbox}
+ END
+ END
+ IF '${key}'=='merchant sku' and '${value}' != '${EMPTY}'
+ Type Text ${offer_merchant_sku} ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Click ${stores_list_selector}
+ MP: select option in expanded dropdown: ${value}
+ Click ${stores_list_selector}
+ END
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}'
+ Click ${stores_list_selector}
+ MP: select option in expanded dropdown: ${value}
+ Click ${stores_list_selector}
+ END
+ IF '${key}'=='stock quantity' and '${value}' != '${EMPTY}'
+ Type Text ${offer_stock_input} ${value}
+ END
+ IF '${key}'=='unselect store' and '${value}' != '${EMPTY}'
+ Click ${stores_list_selector}
+ MP: select option in expanded dropdown: ${value}
+ Click ${stores_list_selector}
+ END
+ IF '${key}'=='service point' and '${value}' != '${EMPTY}'
+ Click ${offer_service_point_selector}
+ Input Text ${offer_service_point_search_field} ${value}
+ MP: select option in expanded dropdown: ${value}
+ Click ${offer_service_point_selector}
+ END
+ IF '${key}'=='services' and '${value}' != '${EMPTY}'
+ FOR ${index} IN RANGE 30
+ ${services_dropdown_is_disabled}= Get Element Attribute ${offer_services_selector} class
+ IF 'disabled' in '${services_dropdown_is_disabled}'
+ Sleep 1s
+ ELSE
+ BREAK
+ END
+ END
+ Click ${offer_services_selector}
+ MP: select option in expanded dropdown: ${value}
+ Click ${offer_services_selector}
+ END
+ IF '${key}'=='shipment types' and '${value}' != '${EMPTY}'
+ Click ${offer_shipment_types_selector}
+ MP: select option in expanded dropdown: ${value}
+ Click ${offer_shipment_types_selector}
+ END
+ END
+
+MP: add offer price:
+ [Arguments] @{args}
+ Wait Until Element Is Visible ${mp_add_price_button}
+ Click ${mp_add_price_button}
+ ${priceData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='row number' and '${value}' != '${EMPTY}'
+ Set Test Variable ${rowNumber} ${value}
+ ELSE
+ Set Test Variable ${rowNumber} 1
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[1]//spy-select
+ MP: select option in expanded dropdown: ${value}
+ END
+ IF '${key}'=='currency' and '${value}' != '${EMPTY}'
+ Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[2]//spy-select
+ MP: select option in expanded dropdown: ${value}
+ END
+ IF '${key}'=='gross default' and '${value}' != '${EMPTY}'
+ Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[4]//input ${value}
+ END
+ IF '${key}'=='quantity' and '${value}' != '${EMPTY}'
+ Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[7]//input ${value}
+ END
+ END
+
+MP: save offer
+ MP: click submit button
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${offerSaved}= Run Keyword And Ignore Error Wait Until Element Is Visible ${offer_saved_popup} timeout=1s
+ Restore Automatic Screenshots on Failure
+ ### resave in case of error
+ IF 'FAIL' in $offerSaved
+ TRY
+ MP: click submit button timeout=1s
+ Wait Until Element Is Visible ${offer_saved_popup} timeout=1s
+ EXCEPT
+ Log Offer is already saved
+ END
+
+ END
+ MP: remove notification wrapper
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: change offer stock:
+ [Arguments] @{args}
+ MP: open navigation menu tab: Offers
+ ${stockData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{stockData}
+ IF '${key}'=='offer' and '${value}' != '${EMPTY}'
+ MP: perform search by: ${value}
+ MP: click on a table row that contains: ${value}
+ Wait Until Element Is Visible ${offer_active_checkbox}
+ END
+ IF '${key}'=='stock quantity' and '${value}' != '${EMPTY}'
+ Type Text ${offer_stock_input} ${value}
+ END
+ IF '${key}'=='is never out of stock' and '${value}' != '${EMPTY}'
+ ${checkbox_state}= Get Element Attribute ${offer_always_in_stock_checkbox} class
+ IF 'checked' in '${checkbox_state}' and '${value}' == 'false'
+ Click ${offer_always_in_stock_checkbox}
+ ELSE IF 'checked' not in '${checkbox_state}' and '${value}' == 'true'
+ Click ${offer_always_in_stock_checkbox}
+ END
+ END
+ END
+ MP: save offer
+
+MP: delete offer price row that contains quantity:
+ [Arguments] ${quantity}
+ Scroll Element Into View xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[7][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Hover xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[7][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Click ${product_delete_price_row_button}
+ Wait Until Element Is Visible ${product_price_deleted_popup}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: remove notification wrapper
+
+Zed: view offer page is displayed
+ Wait Until Element Is Visible ${zed_view_offer_page_main_content_locator}
+
+Zed: view offer product page contains:
+ [Arguments] @{args}
+ ${offerData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{offerData}
+ IF '${key}'=='approval status' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_approval_status} ${value}
+ END
+ IF '${key}'=='status' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_status} ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_store} ${value}
+ END
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_sku} ${value}
+ END
+ IF '${key}'=='name' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_name} ${value}
+ END
+ IF '${key}'=='merchant' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_merchant} ${value}
+ END
+ IF '${key}'=='merchant sku' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_merchant_sku} ${value}
+ END
+ IF '${key}'=='services' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_services} ${value}
+ END
+ IF '${key}'=='shipment types' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_offer_shipment_types} ${value}
+ END
+
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/mp_orders_steps.robot b/atest/testdata/performance/resources/steps/mp_orders_steps.robot
new file mode 100644
index 0000000..c6f339c
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_orders_steps.robot
@@ -0,0 +1,69 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../pages/mp/mp_order_drawer.robot
+
+*** Keywords ***
+MP: wait for order to appear:
+ [Arguments] ${orderReference} ${tries}=20 ${timeout}=1s
+ Trigger oms
+ FOR ${index} IN RANGE 0 ${tries}
+ MP: perform search by: ${orderReference}
+ Disable Automatic Screenshots on Failure
+ ${elementAppears}= Run Keyword And Return Status Table Should Contain ${mp_items_table} ${orderReference}
+ Restore Automatic Screenshots on Failure
+ IF '${elementAppears}'=='False'
+ Sleep ${timeout}
+ Reload
+ ELSE
+ Exit For Loop
+ END
+ END
+ IF ${index} == ${tries}-1
+ Take Screenshot EMBED fullPage=True
+ Fail 'Timeout exceeded, merchant order was not created'
+ END
+
+MP: order grand total should be:
+ [Arguments] ${expectedTotal}
+ Wait Until Element Is Visible ${order_grand_total}
+ Element Text Should Be ${order_grand_total} ${expectedTotal}
+
+MP: order states on drawer should contain:
+ [Arguments] ${expectedState}
+ Wait Until Element Is Visible ${order_state_label_on_drawer}
+ Element Should Contain ${order_state_label_on_drawer} ${expectedState}
+
+MP: update order state using header button:
+ [Arguments] ${buttonName}
+ Wait Until Element Is Enabled xpath=//div[@class='mp-manage-order__transitions']//button[.//text()[normalize-space()='${buttonName}']]
+ Click xpath=//div[@class='mp-manage-order__transitions']//button[.//text()[normalize-space()='${buttonName}']]
+ Wait For Response
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${mp_success_flyout}
+ MP: remove notification wrapper
+ Trigger oms
+
+MP: change order item state on:
+ [Arguments] ${sku} ${state}
+ Wait Until Element Is Visible xpath=//web-mp-order-items-table[@table-id='web-mp-order-items-table']//spy-table[@class='spy-table']//tbody
+ Click xpath=//web-mp-order-items-table[@table-id='web-mp-order-items-table']//spy-table[@class='spy-table']//tbody//td[contains(@class,'ant-table-cell')]//*[contains(text(),'${sku}')]/ancestor::tr/td//spy-checkbox
+ Click xpath=//*[contains(@class,'table-features')]//*[contains(@class,'batch-actions')]//button[.//text()[normalize-space()='${state}']]
+ Wait For Response
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${mp_success_flyout}
+ MP: remove notification wrapper
+ Trigger oms
+
+MP: order item state should be:
+ [Arguments] ${sku} ${state}
+ Wait Until Element Is Visible xpath=//web-mp-order-items-table[@table-id='web-mp-order-items-table']//spy-table[@class='spy-table']//tbody
+ Page Should Contain Element xpath=//web-mp-order-items-table[@table-id='web-mp-order-items-table']//spy-table[@class='spy-table']//tbody//td[contains(@class,'ant-table-cell')]//*[contains(text(),'${sku}')]/ancestor::tr/td//spy-chips[contains(text(),'${state}')]
diff --git a/atest/testdata/performance/resources/steps/mp_products_steps.robot b/atest/testdata/performance/resources/steps/mp_products_steps.robot
new file mode 100644
index 0000000..c40f590
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_products_steps.robot
@@ -0,0 +1,413 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../pages/mp/mp_product_drawer.robot
+
+*** Keywords ***
+MP: fill product price values:
+ [Arguments] @{args}
+ ${priceData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='product type' and '${value}' == 'concrete'
+ ${checkbox_state}= Get Element Attribute ${mp_use_abstract_price_checkbox} class
+ IF 'checked' in '${checkbox_state}'
+ Click ${mp_use_abstract_price_checkbox}
+ END
+ Wait Until Element Is Visible ${mp_add_concrete_price_button}
+ Click ${mp_add_concrete_price_button}
+ END
+ IF '${key}'=='product type' and '${value}' == 'abstract' Run Keywords
+ ... Wait Until Element Is Visible ${mp_add_price_button}
+ ... AND Click ${mp_add_price_button}
+ IF '${key}'=='row number' and '${value}' != '${EMPTY}'
+ Set Test Variable ${rowNumber} ${value}
+ ELSE
+ Set Test Variable ${rowNumber} 1
+ END
+ IF '${env}' in ['ui_mp_b2b']
+ IF '${key}'=='customer' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[1]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[2]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='currency' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[3]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='gross default' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[5]//input ${value}
+ IF '${key}'=='gross original' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[7]//input ${value}
+ IF '${key}'=='quantity' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[8]//input ${value}
+ END
+ IF '${env}' in ['ui_mp_b2c']
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[1]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='currency' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[2]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='gross default' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[4]//input ${value}
+ IF '${key}'=='gross original' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[6]//input ${value}
+ IF '${key}'=='quantity' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[7]//input ${value}
+ END
+ IF '${env}' in ['ui_suite']
+ IF '${key}'=='customer' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[1]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[2]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='currency' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[3]//spy-select
+ ... AND MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='gross default' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[5]//input ${value}
+ IF '${key}'=='gross original' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[7]//input ${value}
+ IF '${key}'=='quantity' and '${value}' != '${EMPTY}' Type Text xpath=//web-spy-card[@spy-title='Price']//tbody/tr[${rowNumber}]/td[8]//input ${value}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+MP: create multi sku product with following data:
+ [Documentation] Creates new abstract product with 2 variants
+ [Arguments] @{args}
+ ${productData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${mp_submit_button}
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='product sku' and '${value}' != '${EMPTY}' Type Text ${new_product_sku_field} ${value}
+ IF '${key}'=='product name' and '${value}' != '${EMPTY}'
+ Run keywords
+ Type Text ${new_product_name_field} ${value}
+ Click ${new_product_multiple_concretes_option}
+ MP: click submit button
+ Disable Automatic Screenshots on Failure
+ ${is_form_submitted}= Run Keyword And Ignore Error Element Should Not Contain ${mp_submit_button} Next
+ Restore Automatic Screenshots on Failure
+ IF 'FAIL' in $is_form_submitted
+ Sleep 0.5s
+ MP: click submit button
+ END
+ MP: remove notification wrapper
+ END
+ IF '${key}'=='first attribute name' and '${value}' != '${EMPTY}'
+ Run keywords
+ Click ${new_product_super_attribute_first_row_name_selector}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: select option in expanded dropdown: ${value}
+ Click ${new_product_super_attribute_first_row_values_selector}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${key}'=='first attribute first value' and '${value}' != '${EMPTY}' MP: select option in expanded dropdown: ${value}
+ IF '${key}'=='first attribute second value' and '${value}' != '${EMPTY}'
+ Run Keywords
+ MP: select option in expanded dropdown: ${value}
+ Click ${new_product_add_super_attribute_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${new_product_super_attribute_second_row_name_selector}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${key}'=='second attribute name' and '${value}' != '${EMPTY}'
+ Run Keywords
+ MP: select option in expanded dropdown: ${value}
+ Click ${new_product_super_attribute_second_row_values_selector}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ IF '${key}'=='second attribute value' and '${value}' != '${EMPTY}' MP: select option in expanded dropdown: ${value}
+ END
+ Sleep 0.5s
+ Element Should Contain ${new_product_concretes_preview_count} 2
+ Click ${new_product_submit_create_button}
+ Sleep 0.5s
+ Wait Until Element Is Visible ${new_product_created_popup}
+ MP: remove notification wrapper
+
+MP: fill abstract product required fields:
+ [Arguments] @{args}
+ ${productData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${product_name_de_field}
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='product name' and '${value}' != '${EMPTY}'
+ Click ${mp_product_name_field_de_tab}
+ Sleep 1s
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${product_name_field}
+ Type Text ${product_name_field} ${value}
+ Click ${mp_product_name_field_en_tab}
+ Sleep 1s
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${product_name_field}
+ Type Text ${product_name_field} ${value}
+ END
+ IF '${key}'=='product name DE' and '${value}' != '${EMPTY}'
+ Click ${mp_product_name_field_de_tab}
+ Wait Until Element Is Visible ${product_name_field}
+ Type Text ${product_name_field} ${value}
+ END
+ IF '${key}'=='product name EN' and '${value}' != '${EMPTY}'
+ Click ${mp_product_name_field_de_tab}
+ Wait Until Element Is Visible ${product_name_field}
+ Type Text ${product_name_field} ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click ${product_store_selector}
+ ... AND MP: select option in expanded dropdown: ${value}
+ ... AND Click ${product_store_selector}
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click ${product_store_selector}
+ ... AND MP: select option in expanded dropdown: ${value}
+ ... AND Click ${product_store_selector}
+ IF '${key}'=='tax set' and '${value}' != '${EMPTY}' Run Keywords
+ ... Click ${product_tax_selector}
+ ... AND MP: select option in expanded dropdown: ${value}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+MP: save abstract product
+ MP: click submit button
+ Wait Until Element Is Visible ${product_updated_popup}
+ MP: remove notification wrapper
+ MP: Wait until loader is no longer visible
+
+MP: fill concrete product fields:
+ [Arguments] @{args}
+ ${productData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='is active' and '${value}' != '${EMPTY}'
+ ${checkbox_state}= Get Element Attribute xpath=//span[contains(text(),'Concrete Product is active')]/../span[contains(@class,'checkbox')] class
+ IF 'checked' in '${checkbox_state}' and '${value}' == 'false'
+ Click ${product_concrete_active_checkbox}
+ ELSE IF 'checked' not in '${checkbox_state}' and '${value}' == 'true'
+ Click ${product_concrete_active_checkbox}
+ END
+ END
+ IF '${key}'=='stock quantity' and '${value}' != '${EMPTY}'
+ Type Text ${product_concrete_stock_input} ${value}
+ END
+ IF '${key}'=='use abstract name' and '${value}' != '${EMPTY}'
+ ${checkbox_state}= Get Element Attribute xpath=//span[contains(text(),'Use Abstract Product name')]/../../span[contains(@class,'checkbox')] class
+ IF 'checked' in '${checkbox_state}' and '${value}' == 'false'
+ Click ${product_concrete_use_abstract_name_checkbox}
+ ELSE IF 'checked' not in '${checkbox_state}' and '${value}' == 'true'
+ Click ${product_concrete_use_abstract_name_checkbox}
+ END
+ END
+ IF '${key}'=='searchability' and '${value}' != '${EMPTY}'
+ Click ${product_concrete_searchability_selector}
+ MP: select option in expanded dropdown: ${value}
+ END
+ END
+ MP: save concrete product
+
+MP: save concrete product
+ Click ${product_concrete_submit_button}
+ TRY
+ Wait Until Element Is Visible ${product_updated_popup}
+ EXCEPT
+ ${page_contains_submit_button}= Run Keyword And Return Status Page Should Contain Element ${product_concrete_submit_button} timeout=10ms
+ IF ${page_contains_submit_button}
+ Click With Options ${product_concrete_submit_button} force=True
+ Wait Until Element Is Visible ${product_updated_popup}
+ END
+ END
+ MP: remove notification wrapper
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: delete product price row that contains text:
+ [Arguments] ${rowContent}
+ Scroll Element Into View xpath=//spy-chips[contains(text(),'${rowContent}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Hover xpath=//spy-chips[contains(text(),'${rowContent}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Click ${product_delete_price_row_button}
+ Wait Until Element Is Visible ${product_price_deleted_popup}
+ MP: remove notification wrapper
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+
+MP: open concrete drawer by SKU:
+ [Arguments] ${concreteSKU}
+ Click ${product_drawer_concretes_tab}
+ MP: click on a table row that contains: ${concreteSKU}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: Wait until loader is no longer visible
+
+MP: delete product price row that contains quantity:
+ [Arguments] ${quantity}
+ IF '${env}' in ['ui_mp_b2b','ui_suite']
+ Scroll Element Into View xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[8][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Hover xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[8][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Click ${product_delete_price_row_button}
+ Wait Until Element Is Visible ${product_price_deleted_popup}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: remove notification wrapper
+ END
+ IF '${env}' in ['ui_mp_b2c']
+ Scroll Element Into View xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[7][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Hover xpath=//web-spy-card[@spy-title='Price']//tbody/tr/td[7][contains(.,'${quantity}')]/ancestor::tr//td[@class='ng-star-inserted']/div
+ Click ${product_delete_price_row_button}
+ Wait Until Element Is Visible ${product_price_deleted_popup}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: remove notification wrapper
+ END
+
+MP: add new concrete product:
+ [Arguments] @{args}
+ Click ${product_drawer_concretes_tab}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${mp_add_concrete_products_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${productData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='first attribute' and '${value}' != '${EMPTY}'
+ Set Test Variable ${firstAttributeName} ${value}
+ END
+ IF '${key}'=='first attribute value' and '${value}' != '${EMPTY}'
+ Click xpath=//mp-concrete-product-attributes-selector[@class='mp-concrete-product-attributes-selector']//spy-form-item//label[contains(text(),'${firstAttributeName}')]/../..//spy-select
+ Sleep 0.5s
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ MP: select option in expanded dropdown: ${value}
+ Click xpath=//mp-concrete-product-attributes-selector[@class='mp-concrete-product-attributes-selector']//spy-form-item//label[contains(text(),'${firstAttributeName}')]/../..//spy-select
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 0.5s
+ END
+ IF '${key}'=='second attribute' and '${value}' != '${EMPTY}'
+ Set Test Variable ${secondAttributeName} ${value}
+ END
+ IF '${key}'=='second attribute value' and '${value}' != '${EMPTY}'
+ Click xpath=//mp-concrete-product-attributes-selector[@class='mp-concrete-product-attributes-selector']//spy-form-item//label[contains(text(),'${secondAttributeName}')]/../..//spy-select
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 0.5s
+ MP: select option in expanded dropdown: ${value}
+ Click xpath=//mp-concrete-product-attributes-selector[@class='mp-concrete-product-attributes-selector']//spy-form-item//label[contains(text(),'${secondAttributeName}')]/../..//spy-select
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 0.5s
+ END
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${new_product_submit_create_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${is_form_submitted}= Run Keyword And Return Status Wait Until Element Is Not Visible ${new_product_submit_create_button}
+ IF not ${is_form_submitted} Click With Options selector=${new_product_submit_create_button} force=True
+ MP: remove notification wrapper
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/mp_profile_steps.robot b/atest/testdata/performance/resources/steps/mp_profile_steps.robot
new file mode 100644
index 0000000..fa3cf72
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/mp_profile_steps.robot
@@ -0,0 +1,49 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_mp.robot
+Resource ../pages/mp/mp_profile_page.robot
+
+
+*** Keywords ***
+MP: open profile tab:
+ [Arguments] ${profileTabName}
+ Wait Until Element Is Visible xpath=//div[@class='ant-tabs-nav-list']//div[contains(text(),'${profileTabName}')]
+ Click xpath=//div[@class='ant-tabs-nav-list']//div[contains(text(),'${profileTabName}')]
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+MP: change store status to:
+ [Arguments] ${store_status}
+ Wait Until Element Is Visible ${store_status_checkbox}
+ ${store_is_online}= Get Element Attribute ${store_status_checkbox} checked
+ IF ('${store_status}' == 'true' or '${store_status}' == 'online') and '${store_is_online}' != 'true'
+ Click ${store_status_checkbox}
+ ELSE IF ('${store_status}' == 'false' or '${store_status}' == 'offline') and '${store_is_online}' == 'true'
+ Click ${store_status_checkbox}
+ END
+ MP: click submit button
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Wait Until Element Is Visible ${mp_success_flyout} timeout=5s
+ Trigger multistore p&s
+
+MP: update profile fields with following data:
+ [Arguments] @{args}
+ ${profileData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${store_status_checkbox}
+ FOR ${key} ${value} IN &{profileData}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_email_field} ${value} delay=50ms
+ IF '${key}'=='phone' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_phone_field} ${value} delay=50ms
+ IF '${key}'=='delivery time' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_delivery_time_en_field} ${value} delay=50ms
+ IF '${key}'=='data privacy' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_data_privacy_en_field} ${value} delay=50ms
+ IF '${key}'=='profile url en' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_store_profile_url_en_field} ${value} delay=50ms
+ IF '${key}'=='profile url de' and '${value}' != '${EMPTY}' Type Text ${merchant_profile_store_profile_url_de_field} ${value} delay=50ms
+ END
+ Sleep 0.5s
diff --git a/atest/testdata/performance/resources/steps/order_comments_steps.robot b/atest/testdata/performance/resources/steps/order_comments_steps.robot
new file mode 100644
index 0000000..4466e48
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/order_comments_steps.robot
@@ -0,0 +1,123 @@
+*** Settings ***
+Resource ../common/common_yves.robot
+Resource ../common/common.robot
+Resource ../steps/customer_account_steps.robot
+Resource ../pages/zed/zed_order_details_page.robot
+Resource ../pages/yves/yves_order_details_page.robot
+Resource ../pages/yves/yves_shopping_cart_page.robot
+Resource ../common/common_zed.robot
+Resource order_history_steps.robot
+
+*** Keywords ***
+Yves: add comment on cart:
+ [Arguments] ${comment}
+ Click With Options ${shopping_cart_write_comment_placeholder} delay=0.5s force=true
+ Type Text ${shopping_cart_write_comment_placeholder} ${comment} delay=50ms
+ Keyboard Key press Enter
+ Click ${shopping_cart_add_comment_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: check comments are visible or not in cart:
+ [Arguments] ${condition} @{comments}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ FOR ${element} IN @{comments}
+ IF '${env}' in ['ui_suite']
+ IF '${condition}' == 'true' Page Should Contain Element xpath=(//comment-form[@data-qa='component comment-form']//*[contains(text(),'${element}')])[1] message=Comment '${element}' is not visible in the shopping cart but should timeout=${browser_timeout}
+ IF '${condition}' == 'false' Page Should Not Contain Element xpath=(//comment-form[@data-qa='component comment-form']//*[contains(text(),'${element}')])[1] message=Comment '${element}' is visible in the shopping cart but should not timeout=${browser_timeout}
+ ELSE
+ IF '${condition}' == 'true' Page Should Contain Element xpath=(//comment-form[@data-qa='component comment-form']//p[contains(text(),'${element}')])[1] message=Comment '${element}' is not visible in the shopping cart but should timeout=${browser_timeout}
+ IF '${condition}' == 'false' Page Should Not Contain Element xpath=(//comment-form[@data-qa='component comment-form']//p[contains(text(),'${element}')])[1] message=Comment '${element}' is visible in the shopping cart but should not timeout=${browser_timeout}
+ END
+ END
+
+Yves: check comments is visible or not in order:
+ [Arguments] ${condition} @{comments}
+ FOR ${element} IN @{comments}
+ IF '${env}' in ['ui_suite']
+ IF '${condition}' == 'true' Element Should Be Visible xpath=(//comment-thread-list//comment-form[@data-qa='component comment-form']//textarea[contains(text(),'${element}')])[1] message=Comment '${element}' is not visible in BO:order details page but should
+ IF '${condition}' == 'false' Element Should Not Be Visible xpath=(//comment-thread-list//comment-form[@data-qa='component comment-form']//textarea[contains(text(),'${element}')])[1] message=Comment '${element}' is visible in BO:order details page but should not
+ ELSE
+ IF '${condition}' == 'true' Element Should Be Visible xpath=(//comment-form[@data-qa='component comment-form']//p[contains(text(),'${element}')])[1] message=Comment '${element}' is not visible in BO:order details page but should
+ IF '${condition}' == 'false' Element Should Not Be Visible xpath=(//div[contains(@class,"comment-form__readonly")]/p[contains(text(),'${element}')])[1] message=Comment '${element}' is visible in BO:order details page but should not
+ END
+ END
+
+Yves: go to order details page to check comment:
+ [Arguments] ${comment} ${lastPlacedOrder}
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ ${text_entered} Get Text ${yves_order_details_page_comments}
+ IF '${text_entered}' == '${comment}'
+ Log text entered in comments appears in order details page in Yves
+ ELSE
+ Fail comments not added successfully to order details page in Yves
+ END
+
+Zed: check comment appears at order detailed page in zed:
+ [Arguments] ${comment} ${lastPlacedOrder}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${lastPlacedOrder} View
+ Wait Until Element Is Visible ${zed_order_details_page_comments}
+ ${text_entered} Get Text ${zed_order_details_page_comments}
+ IF '${text_entered}' == '${comment}'
+ Log comments added to cart appears in order details page in zed
+ ELSE
+ Fail comments added to cart does not appears in order details page in zed
+ END
+
+Yves: edit comment on cart:
+ [Arguments] ${comment_to_set}
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' not in ['ui_suite'] Click ${shopping_cart_edit_comment_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Fill Text ${shopping_cart_edit_comment_placeholder} ${EMPTY} force=true
+ Fill Text ${shopping_cart_edit_comment_placeholder} ${comment_to_set} force=true
+ Click ${shopping_cart_update_comment_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: delete comment on cart
+ Click ${shopping_cart_remove_comment_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Page Should Not Contain Element ${shopping_cart_remove_comment_button}
+
+Yves: add comment on order in order detail page:
+ [Arguments] ${comment}
+ Click With Options ${order_details_page_add_comments_textbox} delay=0.5s
+ Type Text ${order_details_page_add_comments_textbox} ${comment} delay=50ms
+ Click With Options ${add_comment_button_order_details_page} delay=0.5s
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/order_history_steps.robot b/atest/testdata/performance/resources/steps/order_history_steps.robot
new file mode 100644
index 0000000..1994ac8
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/order_history_steps.robot
@@ -0,0 +1,77 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_yves.robot
+Resource ../steps/header_steps.robot
+Resource ../steps/customer_account_steps.robot
+Resource ../pages/yves/yves_order_history_page.robot
+Resource ../pages/yves/yves_order_details_page.robot
+
+*** Keywords ***
+Yves: go to 'Order History' page
+ Yves: go to URL: /customer/order
+
+Yves: 'View Order/Reorder/Return' on the order history page:
+ [Arguments] ${orderAction} ${lastPlacedOrder}=${lastPlacedOrder}
+ IF '${orderAction}' == 'View Order'
+ Click xpath=//div[contains(@data-qa,'component order-table')]//td[contains(text(),'${lastPlacedOrder}')]/..//a[contains(.,'${orderAction}')]
+ ELSE IF '${orderAction}' == 'Reorder'
+ Click xpath=//div[contains(@data-qa,'component order-table')]//td[contains(text(),'${lastPlacedOrder}')]/..//button[contains(.,'${orderAction}')]
+ ELSE IF '${orderAction}' == 'Return'
+ Click xpath=//div[contains(@data-qa,'component order-table')]//td[contains(text(),'${lastPlacedOrder}')]/..//a[contains(.,'${orderAction}')]
+ END
+
+Yves: reorder all items from 'Order Details' page
+ Wait Until Element Is Visible ${order_details_reorder_all_button}[${env}]
+ Click With Options ${order_details_reorder_all_button}[${env}] delay=1s
+ Yves: remove flash messages
+
+Yves: shipping address on the order details page is:
+ [Arguments] ${expectedShippingAddress}
+ ${actualShippingAddress}= Get Text ${order_details_shipping_address_locator}[${env}]
+ ${actualShippingAddress}= Replace String ${actualShippingAddress} \n ${SPACE}
+ Should Be Equal ${expectedShippingAddress} ${actualShippingAddress}
+
+Yves: 'Order Details' page contains the following product title N times:
+ [Arguments] ${productTitle} ${expectedQuantity}
+ Wait Until Page Contains Element xpath=//customer-reorder-form[@data-qa='component customer-reorder-form']//div[@data-qa='component order-detail-table'] | //div[@data-qa='component order-detail-table']
+ IF '${env}' in ['ui_suite']
+ ${productTitleCount}= Get Element Count xpath=//div[@data-qa='component order-detail-table']//article//*[contains(.,'${productTitle}')]/ancestor::article
+ ELSE
+ ${productTitleCount}= Get Element Count xpath=//div[@data-qa='component order-detail-table']//article//*[contains(@class,'title')][text()='${productTitle}']
+ END
+ ${productTitleCount}= Convert To String ${productTitleCount}
+ Should Be Equal ${productTitleCount} ${expectedQuantity}
+
+Yves: 'Order History' page contains the following order with a status:
+ [Arguments] ${orderID} ${expectedStatus}
+ ${actualOrderStatus}= Get Text xpath=//div[contains(@data-qa,'component order-table')]//td[contains(text(),'${orderID}')]/..//*[@data-qa='component status']/..//ancestor::td
+ Should Contain ${actualOrderStatus} ${expectedStatus} msg=None values=True ignore_case=True
+
+Yves: 'Order History' page contains the following order:
+ [Arguments] ${expectedOrderReference}
+ Page Should Contain Element xpath=//div[contains(@data-qa,'component order-table')]//td[contains(text(),'${expectedOrderReference}')]
+
+Yves: 'Order Details' page contains the cancel order button:
+ [Arguments] ${condition}
+ ${condition}= Convert To Lower Case ${condition}
+ IF '${condition}' == 'true'
+ Element Should Be Visible ${order_details_cancel_button_locator}
+ ELSE
+ Element Should Not Be Visible ${order_details_cancel_button_locator}
+ END
+
+Yves: filter order history by business unit:
+ [Arguments] ${business_unit}
+ Wait Until Element Is Visible ${order_history_search_filter_button}
+ ${is_form_open}= Run Keyword And Ignore Error Page Should Contain Element ${order_history_apply_filter_button} timeout=400ms
+ IF 'PASS' in $is_form_open
+ Log Form is active
+ ELSE
+ Click ${order_history_search_filter_button}
+ END
+ Wait Until Element Is Visible ${order_history_apply_filter_button}
+ Click ${order_history_search_filter_business_unit_dropdown}
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-orderSearchForm_filters_companyBusinessUnit-result')][contains(.,'${business_unit}')]
+ Click xpath=//li[contains(@id,'select2-orderSearchForm_filters_companyBusinessUnit-result')][contains(.,'${business_unit}')]
+ Wait Until Element Is Not Visible xpath=//li[contains(@id,'select2-orderSearchForm_filters_companyBusinessUnit-result')][contains(.,'${business_unit}')]
+ Click ${order_history_apply_filter_button}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/orders_management_steps.robot b/atest/testdata/performance/resources/steps/orders_management_steps.robot
new file mode 100644
index 0000000..a2d773c
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/orders_management_steps.robot
@@ -0,0 +1,469 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_zed.robot
+Resource ../pages/yves/yves_return_slip_page.robot
+Resource ../pages/zed/zed_create_return_page.robot
+Resource ../pages/zed/zed_return_details_page.robot
+Resource ../steps/order_history_steps.robot
+Resource ../pages/zed/zed_order_details_page.robot
+
+*** Keywords ***
+Zed: go to order page:
+ [Arguments] ${orderID}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ ${is_order_page_loaded}= Run Keyword And Return Status Page Should Contain Element ${zed_order_details_main_content_locator}
+ IF not ${is_order_page_loaded}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ Wait Until Page Contains Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ END
+
+Zed: go to my order page:
+ [Documentation] Marketplace specific method, to see this page you should be logged in as zed_spryker_merchant_admin_email
+ [Arguments] ${orderID} ${delay}=10s ${iterations}=15
+ Zed: go to URL: /merchant-sales-order-merchant-user-gui
+ Zed: perform search by: ${orderID}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${merchant_order_is_created}= Run Keyword And Return Status Page Should Contain Element xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${orderID}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')] timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${merchant_order_is_created}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected merchant order with reference '${orderID}' is not available/was not created'. Check if OMS is functional
+ END
+ END
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ ${is_order_page_loaded}= Run Keyword And Return Status Page Should Contain Element ${zed_order_details_main_content_locator}
+ IF not ${is_order_page_loaded}
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Zed: go to URL: /merchant-sales-order-merchant-user-gui
+ Zed: perform search by: ${orderID}
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ Wait Until Page Contains Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ END
+
+Zed: trigger all matching states inside xxx order:
+ [Arguments] ${orderID} ${status}
+ Zed: go to order page: ${orderID}
+ ${is_order_page_loaded}= Run Keyword And Return Status Page Should Contain Element ${zed_order_details_main_content_locator}
+ IF not ${is_order_page_loaded}
+ Zed: go to order page: ${orderID}
+ Wait Until Page Contains Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ END
+ Zed: trigger all matching states inside this order: ${status}
+
+Zed: trigger all matching states inside this order:
+ [Arguments] ${status} ${delay}=3s ${iterations}=21
+ Trigger oms
+ Reload
+ Page Should Contain Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${order_state_reached}= Run Keyword And Return Status Page Should Contain Element xpath=//div[@id='order-overview']//form[@name='oms_trigger_form']//button[@id='oms_trigger_form_submit'][text()='${status}']
+ Restore Automatic Screenshots on Failure
+ IF '${order_state_reached}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Scroll Element Into View xpath=(//div[@id='order-overview']//form[@name='oms_trigger_form']//button[@id='oms_trigger_form_submit'])[1]
+ Take Screenshot EMBED fullPage=True
+ ${order_available_states}= Set Variable xpath=//div[@id='order-overview']//form[@name='oms_trigger_form']
+ ${order_available_states_count}= Get Element Count ${order_available_states}
+ ${order_available_states}= Create List
+ FOR ${index} IN RANGE 1 ${order_available_states_count}+1
+ ${order_available_state}= Get Text xpath=(//div[@id='order-overview']//form[@name='oms_trigger_form'])[${index}]
+ Append To List ${order_available_states} ${order_available_state}
+ END
+ Fail Expected order state transition '${status}' is not available. Only '${order_available_states}' is/are available. Check if OMS is functional
+ END
+ END
+ Click and retry if 5xx occurred: xpath=//div[@id='order-overview']//form[@name='oms_trigger_form']//button[@id='oms_trigger_form_submit'][text()='${status}']
+
+Zed: trigger matching state of xxx merchant's shipment:
+ [Documentation] Marketplace specific method, suitable for My Orders of merchant. Triggers action for whole shipment
+ [Arguments] ${shipment_number} ${event} ${delay}=4s ${iterations}=20
+ Trigger oms
+ Reload
+ ${elementSelector}= Set Variable xpath=//div[@id='items']//h3[contains(.,'Shipment ${shipment_number}')]/../../following-sibling::div[2]//form[@name='event_trigger_form']//button[@id='event_trigger_form_submit'][text()='${event}']
+ ${shipment_available_transitions_count}= Get Element Count xpath=//div[@id='items']//h3[contains(.,'Shipment ${shipment_number}')]/../../following-sibling::div[2]//form[@name='event_trigger_form']//button[@id='event_trigger_form_submit']
+ ${shipment_available_transitions}= Create List
+ Set Browser Timeout 1s
+ FOR ${index} IN RANGE 1 ${shipment_available_transitions_count}+1
+ ${shipment_available_transition}= Get Text xpath=(//div[@id='items']//h3[contains(.,'Shipment ${shipment_number}')]/../../following-sibling::div[2]//form[@name='event_trigger_form']//button[@id='event_trigger_form_submit'])[${index}]
+ Append To List ${shipment_available_transitions} ${shipment_available_transition}
+ END
+ Set Browser Timeout ${browser_timeout}
+ ${shipment_available_transitions}= Convert To String ${shipment_available_transitions}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${expected_oms_transition_is_available}= Run Keyword And Return Status Page Should Contain Element ${elementSelector} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${expected_oms_transition_is_available}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected shipment state transition '${event}' for shipment# '${shipment_number}' is not available. Only '${shipment_available_transitions}' is/are available. Check if OMS is functional
+ END
+ END
+ Click and retry if 5xx occurred: ${elementSelector}
+
+Zed: trigger matching state of order item inside xxx shipment:
+ [Arguments] ${sku} ${event} ${shipment}=1 ${delay}=4s ${iterations}=20
+ Trigger oms
+ Reload
+ IF '${env}' in ['ui_mp_b2b','ui_mp_b2c']
+ ${elementSelector}= Set Variable xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td/form[@name='event_item_trigger_form']//button[contains(text(),'${event}')]
+ ELSE
+ ${elementSelector}= Set Variable xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//td/div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr/td/form[@class='oms-trigger-form']//button[contains(text(),'${event}')]
+ END
+ IF '${env}' in ['ui_mp_b2b','ui_mp_b2c']
+ ${item_available_transition_selector}= Set Variable xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td/form[@name='event_item_trigger_form']//button
+ ELSE
+ ${item_available_transition_selector}= Set Variable xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//td/div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr/td/form[@class='oms-trigger-form']//button
+ END
+ ${item_available_transitions_count}= Get Element Count ${item_available_transition_selector}
+ ${item_available_transitions}= Create List
+ Set Browser Timeout 1s
+ ${item_available_transition}= Set Variable
+ FOR ${index} IN RANGE 1 ${item_available_transitions_count}+1
+ IF '${env}' in ['ui_mp_b2b','ui_mp_b2c']
+ ${item_available_transition}= Get Text xpath=(//table[@data-qa='order-item-list'][${shipment}]/tbody//td//div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr//td/form[@name='event_item_trigger_form']//button)[${index}]
+ ELSE
+ ${item_available_transition}= Get Text xpath=(//table[@data-qa='order-item-list'][${shipment}]/tbody//td/div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr/td/form[@class='oms-trigger-form']//button)[${index}]
+ END
+ Append To List ${item_available_transitions} ${item_available_transition}
+ END
+ Set Browser Timeout ${browser_timeout}
+ ${item_available_transition}= Convert To String ${item_available_transition}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${expected_oms_transition_is_available}= Run Keyword And Return Status Page Should Contain Element ${elementSelector} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${expected_oms_transition_is_available}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected item state transition '${event}' for item '${sku}' is not available. Only '${item_available_transitions}' is/are available. Check if OMS is functional
+ END
+ END
+ Click and retry if 5xx occurred: ${elementSelector}
+
+Zed: trigger matching state of xxx order item inside xxx shipment:
+ [Arguments] ${event} ${item_number}=1 ${shipment}=1 ${delay}=4s ${iterations}=20
+ Trigger oms
+ Reload
+ ${elementSelector}= Set Variable xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${item_number}]//td//form[contains(@name,'trigger_form')]//button[contains(text(),'${event}')]
+ ${item_available_transitions_count}= Get Element Count xpath=//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${item_number}]//td//form[contains(@name,'trigger_form')]//button
+ ${item_available_transitions}= Create List
+ Set Browser Timeout 1s
+ FOR ${index} IN RANGE 1 ${item_available_transitions_count}+1
+ ${item_available_transition}= Get Text xpath=(//table[@data-qa='order-item-list'][${shipment}]/tbody//tr[${item_number}]//td//form[contains(@name,'trigger_form')]//button)[${index}]
+ Append To List ${item_available_transitions} ${item_available_transition}
+ END
+ Set Browser Timeout ${browser_timeout}
+ ${item_available_transitions}= Convert To String ${item_available_transitions}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${expected_oms_transition_is_available}= Run Keyword And Return Status Page Should Contain Element ${elementSelector} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${expected_oms_transition_is_available}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected item state transition '${event}' for item number '${item_number}' is not available in shipment# '${shipment}'. Only '${item_available_transitions}' is/are available. Check if OMS is functional
+ END
+ END
+ Click and retry if 5xx occurred: ${elementSelector}
+
+Zed: wait for order item to be in state:
+ [Arguments] ${sku} ${state} ${shipment}=1 ${delay}=10s ${iterations}=20
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${order_item_state_reached}= Run Keyword And Return Status Page Should Contain Element xpath=(//table[@data-qa='order-item-list'][${shipment}]/tbody//td/div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr/td[@class='state-history']//a[contains(text(),'${state}')])[1] timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${order_item_state_reached}'=='False'
+ Run Keywords Sleep ${delay} AND Reload
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger oms
+ END
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ ${order_item_current_state}= Get Text xpath=(//table[@data-qa='order-item-list'][${shipment}]/tbody//td/div[@class='sku'][contains(text(),'${sku}')]/ancestor::tr/td[@class='state-history'])//a[1][@href]
+ Fail Expected order item state '${state}' is not available for the item '${sku}'. Current order item state is '${order_item_current_state}'. Check if OMS is functional
+ END
+ END
+
+Yves: create return for the following products:
+ [Arguments] @{sku_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ Click xpath=(//form[@name='return_create_form']//div[@data-qa='component return-product-item']//*[contains(text(),'${sku_to_check}')]/ancestor::div[@data-qa='component return-product-item']/../div[contains(@class,'col')]//span[contains(@class,'checkbox')])[1]
+ END
+ Click ${create_return_button}[${env}]
+ Trigger oms
+
+Yves: check that 'Print Slip' contains the following products:
+ [Arguments] @{sku_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ IF 'local' not in '${yves_url}' or 'false' in '${headless}'
+ Click ${return_details_print_slip_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ### Wait until new page (pop-up) is displayed ###
+ Sleep 3s
+ ${context}= Get Browser Catalog
+ ${page_count}= Get Length ${context[0]['contexts'][0]['pages']}
+ IF ${page_count}<2
+ Sleep 7s
+ ${context}= Get Browser Catalog
+ END
+ ${print_slip_page_id}= Evaluate [page['id'] for page in ${context[0]['contexts'][0]['pages']} if '/return/slip-print/' in page['url']]
+ ${print_slip_page_length}= Get Length ${print_slip_page_id}
+ IF ${print_slip_page_length}>0
+ ${print_slip_page_url}= Evaluate [page['url'] for page in ${context[0]['contexts'][0]['pages']} if '/return/slip-print/' in page['url']]
+ ${print_slip_page_url}= Get From List ${print_slip_page_url} 0
+ Go To ${print_slip_page_url}
+ Wait Until Page Contains Element ${return_slip_products_table}
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ Table Should Contain ${return_slip_products_table} ${sku_to_check}
+ END
+ ELSE
+ Log New browser page did not open, there is nothing to switch to
+ END
+ END
+
+Zed: create a return for the following order and product in it:
+ [Arguments] ${orderID} @{sku_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ ${is_order_page_loaded}= Run Keyword And Return Status Page Should Contain Element ${zed_order_details_main_content_locator}
+ IF not ${is_order_page_loaded}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ Wait Until Page Contains Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ END
+ Wait Until Page Contains Element xpath=//div[@class='title-action']/a[contains(.,'Return')]
+ Click Element by xpath with JavaScript //div[@class='title-action']/a[contains(.,'Return')]
+ Wait Until Page Contains Element ${zed_create_return_main_content_locator}
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ Click xpath=//table[@data-qa='order-item-list']//td/div[contains(@class,'sku')][contains(.,'${sku_to_check}')]/ancestor::tr//div[@class='form-check']//input
+ END
+ Click ${zed_create_return_button}
+ Wait Until Page Contains Element ${zed_return_details_main_content_locator}
+ Trigger oms
+
+Zed: grand total for the order equals:
+ [Arguments] ${orderID} ${grandTotal}
+ Zed: go to URL: /sales
+ Zed: perform search by: ${orderID}
+ Table Should Contain ${zed_table_locator} ${grandTotal}
+
+Zed: get the last placed order ID of the customer by email:
+ [Documentation] Returns orderID of the last order from the Backoffice by email
+ [Arguments] ${email}
+ Zed: go to URL: /sales
+ Zed: perform search by: ${email}
+ ${zedLastPlacedOrder}= Get Text xpath=//table[contains(@data-ajax,'sales')][contains(@class,'dataTable')]/tbody/tr[1]/td[2]
+ Set Suite Variable ${zedLastPlacedOrder} ${zedLastPlacedOrder}
+ RETURN ${zedLastPlacedOrder}
+
+Zed: order has the following number of shipments:
+ [Arguments] ${orderID} ${expectedShipments} ${timeout}=5s
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ ${is_order_page_loaded}= Run Keyword And Return Status Page Should Contain Element ${zed_order_details_main_content_locator}
+ IF not ${is_order_page_loaded}
+ Zed: go to URL: /sales
+ Zed: click Action Button in a table for row that contains: ${orderID} View
+ Wait Until Page Contains Element ${zed_order_details_main_content_locator} message=Order details page is not loaded
+ END
+ TRY
+ Wait Until Element Is Visible xpath=//table[@data-qa='order-item-list'][1] timeout=${timeout}
+ EXCEPT
+ Reload
+ Wait Until Element Is Visible xpath=//table[@data-qa='order-item-list'][1]
+ END
+ ${actualShipments}= Get Element Count xpath=//table[@data-qa='order-item-list']
+ Should Be Equal '${expectedShipments}' '${actualShipments}' msg=Expected '${expectedShipments}' number of shipments inside the '${orderID}' order, but got '${actualShipments}'
+
+Zed: return details page contains the following items:
+ [Arguments] @{sku_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ Wait Until Page Contains Element ${zed_return_details_main_content_locator}
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ Page Should Contain Element xpath=//table[@data-qa='return-items-table']//td//a[contains(@href,'view/variant')]/../div[@class='sku'][contains(.,'${sku_to_check}')] message=Return details page doesn't contain '${sku_list}' but should.
+ END
+
+Zed: view the latest return from My Returns:
+ [Arguments] ${return_id}
+ Zed: click Action Button in a table for row that contains: ${return_id} View
+ Wait Until Page Contains Element ${zed_return_details_main_content_locator}
+
+Zed: billing address for the order should be:
+ [Arguments] ${expected_billing_address}
+ Wait Until Page Contains Element ${order_details_billing_address}
+ Element Should Contain ${order_details_billing_address} ${expected_billing_address}
+
+Zed: shipping address inside xxx shipment should be:
+ [Arguments] ${shipment} ${expected_address}
+ TRY
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[1] ${expected_address} timeout=5s
+ EXCEPT
+ Reload
+ Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[1] ${expected_address}
+ END
+
+Zed: create new shipment inside the order:
+ [Arguments] @{args}
+ ${newShipmentData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${create_shipment_button}
+ Click ${create_shipment_button}
+ Wait Until Element Is Visible ${create_shipment_delivery_address_dropdown}
+ FOR ${key} ${value} IN &{newShipmentData}
+ IF '${key}'=='delivery address' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_delivery_address_dropdown} ${value}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_salutation_dropdown} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${create_shipment_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${create_shipment_last_name_field} ${value}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${create_shipment_email_field} ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_country_dropdown} ${value}
+ IF '${key}'=='address 1' and '${value}' != '${EMPTY}' Type Text ${create_shipment_address_1_field} ${value}
+ IF '${key}'=='address 2' and '${value}' != '${EMPTY}' Type Text ${create_shipment_address_2_field} ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text ${create_shipment_city_field} ${value}
+ IF '${key}'=='zip code' and '${value}' != '${EMPTY}' Type Text ${create_shipment_zip_code_field} ${value}
+ IF '${key}'=='shipment method' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_shipment_method} ${value}
+ IF '${key}'=='requested delivery date' and '${value}' != '${EMPTY}' Type Text ${create_shipment_requested_delivery_date} ${value}
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 2' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 3' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 4' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 5' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ END
+ Zed: submit the form
+ Wait Until Element Is Visible ${order_details_billing_address}
+
+Zed: edit xxx shipment inside the order:
+ [Arguments] @{args}
+ ${newShipmentData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible xpath=(//div[@class='ibox-content']//a[contains(@href,'shipment-gui/edit')])[${shipmentN}]
+ Click ${create_shipment_button}
+ Wait Until Element Is Visible ${create_shipment_delivery_address_dropdown}
+ FOR ${key} ${value} IN &{newShipmentData}
+ IF '${key}'=='delivery address' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_delivery_address_dropdown} ${value}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_salutation_dropdown} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${create_shipment_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${create_shipment_last_name_field} ${value}
+ IF '${key}'=='email' and '${value}' != '${EMPTY}' Type Text ${create_shipment_email_field} ${value}
+ IF '${key}'=='country' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_country_dropdown} ${value}
+ IF '${key}'=='address 1' and '${value}' != '${EMPTY}' Type Text ${create_shipment_address_1_field} ${value}
+ IF '${key}'=='address 2' and '${value}' != '${EMPTY}' Type Text ${create_shipment_address_2_field} ${value}
+ IF '${key}'=='city' and '${value}' != '${EMPTY}' Type Text ${create_shipment_city_field} ${value}
+ IF '${key}'=='zip code' and '${value}' != '${EMPTY}' Type Text ${create_shipment_zip_code_field} ${value}
+ IF '${key}'=='shipment method' and '${value}' != '${EMPTY}' Select From List By Label ${create_shipment_shipment_method} ${value}
+ IF '${key}'=='requested delivery date' and '${value}' != '${EMPTY}' Type Text ${create_shipment_requested_delivery_date} ${value}
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 2' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 3' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 4' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ IF '${key}'=='sku 5' and '${value}' != '${EMPTY}' Check Checkbox xpath=//table[@data-qa='order-item-list']/tbody//td//div[@class='sku'][contains(.,'${value}')]/ancestor::tr/td[@class='item-checker']//input
+ END
+ Zed: submit the form
+ Wait Until Element Is Visible ${order_details_billing_address}
+
+Zed: shipment data inside xxx shipment should be:
+ [Arguments] @{args}
+ ${shipmentData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{shipmentData}
+ IF '${key}'=='shipment n' and '${value}' != '${EMPTY}'
+ ${shipment}= Set Variable ${value}
+ END
+ IF '${key}'=='shipment n' and '${value}' == '${EMPTY}'
+ ${shipment}= Set Variable 1
+ END
+ IF '${key}'=='delivery method' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[2] ${value}
+ IF '${key}'=='shipping method' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[3] ${value}
+ IF '${key}'=='shipping costs' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[4] ${value}
+ IF '${key}'=='requested delivery date' and '${value}' != '${EMPTY}' Element Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}]/preceding-sibling::div[2]//p[5] ${value}
+ END
+
+Zed: xxx shipment should/not contain the following products:
+ [Arguments] ${shipment} ${condition} @{sku_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ ${condition}= Convert To Lower Case ${condition}
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ IF '${condition}' == 'true'
+ Table Should Contain xpath=//table[@data-qa='order-item-list'][${shipment}] ${sku_to_check}
+ END
+ IF '${condition}' == 'false'
+ Table Should Not Contain xpath=//table[@data-qa='order-item-list'][${shipment}] ${sku_to_check}
+ END
+ END
+
+Yves: cancel the order:
+ [Arguments] ${order_id}
+ Trigger oms
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${order_id}
+ Yves: try reloading page if element is/not appear: ${order_details_cancel_button_locator} true
+ Wait Until Element Is Visible ${order_details_cancel_button_locator}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${order_details_cancel_button_locator}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Not Visible ${order_details_cancel_button_locator}
+ Yves: go to 'Order History' page
+ Yves: 'Order History' page contains the following order with a status: ${order_id} Canceled
+ Trigger oms
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/pdp_steps.robot b/atest/testdata/performance/resources/steps/pdp_steps.robot
new file mode 100644
index 0000000..d592823
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/pdp_steps.robot
@@ -0,0 +1,673 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../pages/yves/yves_product_details_page.robot
+Resource ../common/common_yves.robot
+
+*** Variables ***
+${pdpPriceLocator} ${pdp_price_element_locator}
+${addToCartButton} ${pdp_add_to_cart_button}
+${alternativeProducts} ${pdp_alternative_products_slider}[${env}]
+${measurementUnitSuggestion} ${pdp_measurement_unit_notification}
+${packagingUnitSuggestion} ${pdp_packaging_unit_notification}
+${bundleItemsSmall} ${pdp_product_bundle_include_small}[${env}]
+${bundleItemsLarge} ${pdp_product_bundle_include_large}
+${relatedProducts} ${pdp_related_products}[${env}]
+${bazaarvoiceWriteReview} ${pdp_bazaarvoice_write_review_button}
+${bazaarvoiceQuestions} ${pdp_bazaarvoice_questions_locator}
+${bazaarvoiceInlineRating} ${pdp_bazaarvoice_intine_rating_locator}
+${configureButton} ${pdp_configure_button}
+
+*** Keywords ***
+Yves: PDP contains/doesn't contain:
+ [Arguments] ${condition} @{pdp_elements_list}
+ ${condition}= Convert To Lower Case ${condition}
+ ${pdp_elements_list_count}= get length ${pdp_elements_list}
+ FOR ${index} IN RANGE 0 ${pdp_elements_list_count}
+ ${pdp_element_to_check}= Get From List ${pdp_elements_list} ${index}
+ IF '${condition}' == 'true'
+ Run Keywords
+ Log ${pdp_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Contain Element ${pdp_element_to_check} message=${pdp_element_to_check} is not displayed
+ END
+ IF '${condition}' == 'false'
+ Run Keywords
+ Log ${pdp_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Not Contain Element ${pdp_element_to_check} message=${pdp_element_to_check} should not be displayed
+ END
+ END
+
+Yves: add product to the shopping cart
+ [Arguments] ${wait_for_p&s}=${False} ${iterations}=26 ${delay}=3s
+ Disable Automatic Screenshots on Failure
+ ${variants_present_status}= Run Keyword And Return Status Page Should Not Contain Element ${pdp_variant_selector} timeout=0:00:01
+ Restore Automatic Screenshots on Failure
+ IF '${variants_present_status}'=='False' Yves: change variant of the product on PDP on random value
+ ${wait_for_p&s}= Convert To String ${wait_for_p&s}
+ ${wait_for_p&s}= Convert To Lower Case ${wait_for_p&s}
+ IF '${wait_for_p&s}' == 'true'
+ ${wait_for_p&s}= Set Variable ${True}
+ END
+ IF '${wait_for_p&s}' == 'false'
+ ${wait_for_p&s}= Set Variable ${False}
+ END
+ IF ${wait_for_p&s}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${result}= Run Keyword And Ignore Error Wait Until Element Is Enabled ${pdp_add_to_cart_button} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail 'Add to cart' button is not actionable/available on PDP
+ END
+ IF 'FAIL' in $result
+ Sleep ${delay}
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Continue For Loop
+ ELSE
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${pdp_add_to_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Exit For Loop
+ END
+ END
+ ELSE
+ Click ${pdp_add_to_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+
+Yves: change quantity on PDP:
+ [Arguments] ${qtyToSet}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Type Text ${pdp_quantity_input_filed}[${env}] ${qtyToSet}
+ Keyboard Key press Enter
+ Sleep 1s
+ ELSE IF '${env}' in ['ui_suite']
+ Select From List By Value ${pdp_quantity_input_filed}[${env}] ${qtyToSet}
+ ELSE
+ Add/Edit element attribute with JavaScript: ${pdp_quantity_input_filed}[${env}] value ${qtyToSet}
+ Click ${pdp_product_name}
+ END
+
+Yves: select the following 'Sales Unit' on PDP:
+ [Arguments] ${salesUnit}
+ Wait Until Element Is Visible ${pdp_measurement_sales_unit_selector}
+ Select From List By Label ${pdp_measurement_sales_unit_selector} ${salesUnit}
+
+Yves: change quantity using '+' or '-' button № times:
+ [Arguments] ${action} ${clicksCount}
+ FOR ${index} IN RANGE 0 ${clicksCount}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${action}' == '+'
+ Click ${pdp_increase_quantity_button}[${env}]
+ ELSE IF '${action}' == '-'
+ Click ${pdp_decrease_quantity_button}[${env}]
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: set quantity on PDP:
+ [Arguments] ${qty}
+ Type Text xpath=(//formatted-number-input//input)[1] ${qty}
+
+Yves: change variant of the product on PDP on:
+ [Arguments] ${variantToChoose}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Page Contains Element ${pdp_variant_selector}
+ TRY
+ ${timeout}= Set Variable 1s
+ Set Browser Timeout ${timeout}
+ Click ${pdp_variant_custom_selector}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${pdp_variant_custom_selector_results} timeout=${timeout}
+ TRY
+ Set Browser Timeout ${browser_timeout}
+ Click xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]/li[contains(@id,'select2-attribute')][contains(.,'${variantToChoose}')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ EXCEPT
+ Set Browser Timeout ${browser_timeout}
+ Reload
+ Sleep ${timeout}
+ Click xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]/li[contains(@id,'select2-attribute')][contains(.,'${variantToChoose}')]
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ EXCEPT
+ Set Browser Timeout ${timeout}
+ Run Keyword And Ignore Error Select From List By Value ${pdp_variant_selector} ${variantToChoose}
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ Set Browser Timeout ${browser_timeout}
+ Disable Automatic Screenshots on Failure
+ ${variant_selected}= Run Keyword And Return Status Wait For Elements State ${pdp_reset_selected_variant_locator} attached timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF '${variant_selected}'=='False'
+ TRY
+ Set Browser Timeout 1s
+ Click ${pdp_variant_custom_selector}
+ Wait Until Element Is Visible ${pdp_variant_custom_selector_results}
+ TRY
+ Click xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]/li[contains(@id,'select2-attribute')][contains(.,'${variantToChoose}')]
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ EXCEPT
+ Set Browser Timeout ${browser_timeout}
+ Reload
+ Click xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]/li[contains(@id,'select2-attribute')][contains(.,'${variantToChoose}')]
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ EXCEPT
+ ${final_try}= Run Keyword And Ignore Error Select From List By Value ${pdp_variant_selector} ${variantToChoose}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF 'FAIL' in $final_try
+ Take Screenshot EMBED fullPage=True
+ FAIL '${variantToChoose}' variant was not selected on PDP. Check if variant exists
+ END
+ END
+ END
+ Set Browser Timeout ${browser_timeout}
+
+Yves: reset selected variant of the product on PDP
+ Wait Until Page Contains Element ${pdp_reset_selected_variant_locator}
+ Click ${pdp_reset_selected_variant_locator}
+
+Yves: change amount on PDP:
+ [Arguments] ${amountToSet}
+ Type Text ${pdp_amount_input_filed} ${amountToSet}
+
+Yves: product price on the PDP should be:
+ [Arguments] ${expectedProductPrice} ${wait_for_p&s}=${False} ${iterations}=26 ${delay}=5s
+ ### *** promise for P&S *** ####
+ ${wait_for_p&s}= Convert To String ${wait_for_p&s}
+ ${wait_for_p&s}= Convert To Lower Case ${wait_for_p&s}
+ IF '${wait_for_p&s}' == 'true'
+ ${wait_for_p&s}= Set Variable ${True}
+ END
+ IF '${wait_for_p&s}' == 'false'
+ ${wait_for_p&s}= Set Variable ${False}
+ END
+ Set Browser Timeout 1s
+ IF ${wait_for_p&s}
+ FOR ${index} IN RANGE 1 ${iterations}
+ IF ${index} == 2 or ${index} == 5
+ Trigger multistore p&s
+ END
+ Disable Automatic Screenshots on Failure
+ ${price_displayed}= Run Keyword And Ignore Error Page Should Contain Element ${pdp_price_element_locator} timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF 'PASS' in $price_displayed
+ ${actualProductPrice}= Get Text ${pdp_price_element_locator}
+ END
+ Disable Automatic Screenshots on Failure
+ ${result}= Run Keyword And Ignore Error Should Be Equal ${expectedProductPrice} ${actualProductPrice}
+ Restore Automatic Screenshots on Failure
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Actual product price is ${actualProductPrice}, expected ${expectedProductPrice}
+ END
+ IF 'FAIL' in $result or 'FAIL' in $price_displayed
+ Sleep ${delay}
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Continue For Loop
+ ELSE
+ Set Browser Timeout ${browser_timeout}
+ Exit For Loop
+ END
+ END
+ ELSE
+ Set Browser Timeout 1s
+ TRY
+ ${actualProductPrice}= Get Text ${pdp_price_element_locator}
+ Should Be Equal ${expectedProductPrice} ${actualProductPrice} message=Actual product price is ${actualProductPrice}, expected ${expectedProductPrice}
+ EXCEPT
+ Trigger multistore p&s
+ Sleep 3s
+ Set Browser Timeout ${browser_timeout}
+ Reload
+ Take Screenshot EMBED fullPage=True
+ ${actualProductPrice}= Get Text ${pdp_price_element_locator}
+ Should Be Equal ${expectedProductPrice} ${actualProductPrice} message= Actual product price is ${actualProductPrice}, expected ${expectedProductPrice}
+ END
+ Set Browser Timeout ${browser_timeout}
+ END
+
+Yves: product original price on the PDP should be:
+ [Arguments] ${expectedProductPrice}
+ ${actualProductPrice}= Get Text ${pdp_original_price_element_locator}
+ Should Be Equal ${expectedProductPrice} ${actualProductPrice}
+
+Yves: add product to the shopping list:
+ [Documentation] If SL name is not provided, default one will be used
+ [Arguments] ${shoppingListName}=${EMPTY}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ Reload
+ END
+ ${variants_present_status}= Run Keyword And Ignore Error Page Should Not Contain Element ${pdp_variant_selector} timeout=400ms
+ ${shopping_list_dropdown_status}= Run Keyword And Ignore Error Page should contain element ${pdp_shopping_list_selector} timeout=5s
+ IF 'FAIL' in $variants_present_status Yves: change variant of the product on PDP on random value
+ IF ('${shoppingListName}' != '${EMPTY}' and 'PASS' in $shopping_list_dropdown_status)
+ TRY
+ Set Browser Timeout 1s
+ Wait Until Element Is Enabled ${pdp_shopping_list_selector}
+ Select From List By Label ${pdp_shopping_list_selector} ${shoppingListName}
+ Wait Until Element Is Visible ${pdp_add_to_shopping_list_button}
+ Click With Options ${pdp_add_to_shopping_list_button} noWaitAfter=true
+ Set Browser Timeout ${browser_timeout}
+ Wait For Response
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ EXCEPT
+ LocalStorage Clear
+ Reload
+ Set Browser Timeout ${browser_timeout}
+ Click xpath=//span[@class='select2-selection select2-selection--single']//span[contains(@id,'select2-idShoppingList')]
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-idShoppingList')][contains(@id,'result')][contains(.,'${shoppingListName}')]
+ Click xpath=//li[contains(@id,'select2-idShoppingList')][contains(@id,'result')][contains(.,'${shoppingListName}')]
+ Wait Until Element Is Visible ${pdp_add_to_shopping_list_button}
+ Click ${pdp_add_to_shopping_list_button}
+ Set Browser Timeout ${browser_timeout}
+ Wait For Response
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ FINALLY
+ Set Browser Timeout ${browser_timeout}
+ END
+ ELSE
+ Click ${pdp_add_to_shopping_list_button}
+ Wait For Response
+ END
+ Set Browser Timeout ${browser_timeout}
+ Yves: remove flash messages
+
+Yves: change variant of the product on PDP on random value
+ Wait Until Element Is Visible ${pdp_variant_selector}
+ TRY
+ Set Browser Timeout 10s
+ Click With Options ${pdp_variant_custom_selector} force=True
+ Wait Until Element Is Visible ${pdp_variant_custom_selector_results}
+ Click xpath=//ul[contains(@id,'select2-attribute')][contains(@id,'results')]/li[contains(@id,'select2-attribute')][1]
+ EXCEPT
+ Run Keyword And Ignore Error Select From List By Value ${pdp_variant_selector} ${variantToChoose}
+ END
+ Set Browser Timeout ${browser_timeout}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: get sku of the concrete product on PDP
+ Wait Until Element Is Visible ${pdp_product_sku}[${env}]
+ ${got_concrete_product_sku}= Get Text ${pdp_product_sku}[${env}]
+ ${got_concrete_product_sku}= Replace String ${got_concrete_product_sku} SKU: ${EMPTY}
+ ${got_concrete_product_sku}= Replace String ${got_concrete_product_sku} ${SPACE} ${EMPTY}
+ Set Global Variable ${got_concrete_product_sku}
+ RETURN ${got_concrete_product_sku}
+
+Yves: get name of the product on PDP
+ Wait Until Element Is Visible ${pdp_main_container_locator}[${env}]
+ ${got_product_name}= Get Text ${pdp_product_name}
+ ${got_product_name}= Remove leading and trailing whitespace from a string: ${got_product_name}
+ Set Global Variable ${got_product_name}
+ RETURN ${got_product_name}
+
+Yves: get sku of the abstract product on PDP
+ Wait Until Element Is Visible ${pdp_main_container_locator}[${env}]
+ ${currentURL}= Get Url
+ Log current url: ${currentURL}
+ ${got_abstract_product_sku}= Get Regexp Matches ${currentURL} ([^-]+$)
+ ${got_abstract_product_sku}= Convert To String ${got_abstract_product_sku}
+ ${got_abstract_product_sku}= Replace String ${got_abstract_product_sku} ' ${EMPTY}
+ ${got_abstract_product_sku}= Replace String ${got_abstract_product_sku} [ ${EMPTY}
+ ${got_abstract_product_sku}= Replace String ${got_abstract_product_sku} ] ${EMPTY}
+ ${sku_length}= Get Length ${got_abstract_product_sku}
+ ${got_abstract_product_sku}= Set Variable If '${env}'!='ui_b2b' and '${sku_length}'=='2' 0${got_abstract_product_sku} ${got_abstract_product_sku}
+ ${got_abstract_product_sku}= Set Variable If '${env}'!='ui_b2b' and '${sku_length}'=='1' 00${got_abstract_product_sku} ${got_abstract_product_sku}
+ Set Global Variable ${got_abstract_product_sku}
+ RETURN ${got_abstract_product_sku}
+
+Yves: add product to wishlist:
+ [Arguments] ${wishlistName} ${selectWishlist}=
+ Wait Until Element Is Visible ${pdp_add_to_wishlist_button}
+ Wait Until Element Is Enabled ${pdp_add_to_wishlist_button}
+ ${wishlistSelectorExists}= Run Keyword And Return Status Element Should Be Visible ${pdp_wishlist_dropdown}
+ IF '${selectWishlist}'=='select'
+ Run keywords
+ Wait Until Element Is Visible xpath=//select[contains(@name,'wishlist-name')]
+ Wait Until Element Is Enabled xpath=//select[contains(@name,'wishlist-name')]
+ Select From List By Value xpath=//select[contains(@name,'wishlist-name')] ${wishlistName}
+ END
+ Click ${pdp_add_to_wishlist_button}
+
+Yves: check if product is available on PDP:
+ [Arguments] ${abstractSku} ${isAvailable}
+ ${isAvailable}= Convert To Lower Case ${isAvailable}
+ Reload
+ IF '${isAvailable}'=='false'
+ Run keywords
+ Element Should Be Visible ${pdp_product_not_available_text}
+ Element Should Be Visible ${pdp_add_to_cart_disabled_button}[${env}]
+ Element Should Be Visible ${pdp_availability_notification_email_field}
+ ELSE
+ Run keywords
+ Element Should Not Be Visible ${pdp_product_not_available_text}
+ Element Should Not Be Visible ${pdp_add_to_cart_disabled_button}[${env}]
+ Element Should Not Be Visible ${pdp_availability_notification_email_field}
+ Element Should Be Visible ${pdp_add_to_cart_button}
+ END
+
+Yves: submit back in stock notification request for email:
+ [Arguments] ${email}
+ Type Text ${pdp_availability_notification_email_field} ${email}
+ Click ${pdp_back_in_stock_subscribe_button}
+ Yves: flash message should be shown: success Successfully subscribed
+ Yves: remove flash messages
+ Element Should Be Visible xpath=//button[contains(text(),'Do not notify me when back in stock')]
+
+Yves: unsubscribe from availability notifications
+ Click ${pdp_back_in_stock_unsubscribe_button}
+ Yves: flash message should be shown: success Successfully unsubscribed
+ Yves: remove flash messages
+
+Yves: select xxx merchant's offer:
+ [Arguments] ${merchantName}
+ Wait Until Element Is Visible ${pdp_product_sku}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${merchant_offer_is_already_selected}= Run Keyword And Return Status Page Should Contain Element xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input[@checked] timeout=50ms
+ IF not ${merchant_offer_is_already_selected}
+ TRY
+ Click xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]
+ Wait For Request
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input state=checked timeout=3s
+ EXCEPT
+ LocalStorage Clear
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${merchant_offer_is_already_selected}= Run Keyword And Return Status Page Should Contain Element xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input[@checked] timeout=50ms
+ IF not ${merchant_offer_is_already_selected}
+ Click xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]
+ TRY
+ Wait For Request
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ Sleep 50ms
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input state=checked timeout=3s
+ END
+ END
+ Wait Until Element Contains ${referrer_url} offer message=Offer selector radio button does not work on PDP but should
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+
+Yves: select xxx merchant's offer with price:
+ [Arguments] ${merchantName} ${price} ${wait_for_p&s}=${False} ${iterations}=26 ${delay}=3s
+ Wait Until Element Is Visible ${pdp_product_sku}[${env}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ### *** promise for P&S *** ####
+ ${wait_for_p&s}= Convert To String ${wait_for_p&s}
+ ${wait_for_p&s}= Convert To Lower Case ${wait_for_p&s}
+ IF '${wait_for_p&s}' == 'true'
+ ${wait_for_p&s}= Set Variable ${True}
+ END
+ IF '${wait_for_p&s}' == 'false'
+ ${wait_for_p&s}= Set Variable ${False}
+ END
+ IF ${wait_for_p&s}
+ FOR ${index} IN RANGE 1 ${iterations}
+ Disable Automatic Screenshots on Failure
+ ${result}= Run Keyword And Ignore Error Page Should Contain Element xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')] timeout=400ms
+ Restore Automatic Screenshots on Failure
+ IF ${index} == ${iterations}-1
+ Take Screenshot EMBED fullPage=True
+ Fail Expected '${merchantName}' merchant offer with '${price}' is not present on PDP
+ END
+ IF 'FAIL' in $result
+ Sleep ${delay}
+ Reload
+ Continue For Loop
+ ELSE
+ Click xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]
+ Wait For Request
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input state=checked timeout=3s
+ Exit For Loop
+ END
+ END
+ ELSE
+ ${merchant_offer_is_already_selected}= Run Keyword And Return Status Page Should Contain Element xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input[@checked] timeout=50ms
+ IF not ${merchant_offer_is_already_selected}
+ TRY
+ Click xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]
+ Wait For Request
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input state=checked timeout=3s
+ EXCEPT
+ Reload
+ ${merchant_offer_is_already_selected}= Run Keyword And Return Status Page Should Contain Element xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input[@checked] timeout=50ms
+ IF not ${merchant_offer_is_already_selected}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]
+ Wait For Request
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ Wait For Elements State xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'][contains(.,'${price}')]/ancestor::div[contains(@class,'offer-item')]//span[contains(@class,'radio__box')]/../input state=checked timeout=3s
+ END
+ END
+ END
+ Wait Until Element Contains ${referrer_url} offer message=Offer selector radio button does not work on PDP but should
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: merchant's offer/product price should be:
+ [Arguments] ${merchantName} ${expectedProductPrice}
+ Wait Until Element Is Visible ${pdpPriceLocator}
+ Try reloading page until element does/not contain text: xpath=//section[@data-qa='component product-configurator']//*[contains(text(),'${merchantName}')]/ancestor::div[contains(@class,'item')]//span[@itemprop='price'] ${expectedProductPrice} true 21 5s
+
+Yves: merchant is (not) displaying in Sold By section of PDP:
+ [Arguments] ${merchantName} ${condition}
+ Wait Until Element Is Visible ${pdp_product_sku}[${env}]
+ TRY
+ Try reloading page until element is/not appear: xpath=//section[@data-qa='component product-configurator']//*[contains(@data-qa,'merchant-product')]//*[contains(text(),'${merchantName}')] ${condition} 4 10s
+ EXCEPT
+ Trigger multistore p&s
+ ${currentURL}= Get Url
+ Try reloading page until element is/not appear: xpath=//section[@data-qa='component product-configurator']//*[contains(@data-qa,'merchant-product')]//*[contains(text(),'${merchantName}')] ${condition} 6 10s
+ END
+
+Yves: select random varian if variant selector is available
+ ${variants_present_status}= Run Keyword And Return Status Page should contain element ${pdp_variant_selector} ${EMPTY} 0:00:01
+ IF '${variants_present_status}'=='True' Yves: change variant of the product on PDP on random value
+
+Yves: try add product to the cart from PDP and expect error:
+ [Arguments] ${expectedError}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click ${pdp_add_to_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: flash message should be shown: error ${expectedError}
+
+Yves: product name on PDP should be:
+ [Arguments] ${expected_product_name}
+ Yves: try reloading page if element is/not appear: xpath=//h1[contains(@class,'title')][contains(.,'${expected_product_name}')] True 15 3s
+
+Yves: try to add product to wishlist as guest user
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${pdp_add_to_wishlist_button}
+ SessionStorage Clear
+ TRY
+ LocalStorage Clear
+ EXCEPT
+ Log Failed to clear LocalStorage
+ END
+ Delete All Cookies
+ Click ${pdp_add_to_wishlist_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${email_field}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/picking_list_steps.robot b/atest/testdata/performance/resources/steps/picking_list_steps.robot
new file mode 100644
index 0000000..4e807d7
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/picking_list_steps.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Remove picking list by uuid in DB:
+ [Documentation] This keyword deletes the entry from the DB table `spy_picking_list`.
+ ... *Example:*
+ ...
+ ... ``Remove picking list by uuid in DB: ${pick_list_uuid}``
+ ...
+ [Arguments] ${pick_list_uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_picking_list WHERE uuid = '${pick_list_uuid}';
+ Disconnect From Database
+
+Remove picking list item by uuid in DB:
+ [Documentation] This keyword deletes the entry from the DB table `spy_warehouse_user_assignment`.
+ ... *Example:*
+ ...
+ ... ``Remove picking list item by uuid in DB: ${pick_list_item_uuid}``
+ ...
+ [Arguments] ${pick_list_item_uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_picking_list_item WHERE uuid = '${pick_list_item_uuid}';
+ Disconnect From Database
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/product_set_steps.robot b/atest/testdata/performance/resources/steps/product_set_steps.robot
new file mode 100644
index 0000000..7255f40
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/product_set_steps.robot
@@ -0,0 +1,169 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../pages/yves/yves_product_sets_page.robot
+Resource ../common/common_yves.robot
+Resource ../common/common_zed.robot
+Resource ../pages/zed/zed_product_set_page.robot
+
+*** Keywords ***
+Yves: 'Product Sets' page contains the following sets:
+ [Arguments] @{product_set_list}
+ ${product_set_list_count}= get length ${product_set_list}
+ FOR ${index} IN RANGE 0 ${product_set_list_count}
+ ${product_set_to_check}= Get From List ${product_set_list} ${index}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Page Should Contain Element xpath=//*[contains(@class,'product-set-card__name')][text()="${product_set_to_check}"]/ancestor::article
+ ELSE IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//article//*[contains(@class,'box')][contains(.,'${product_set_to_check}')]/ancestor::article
+ ELSE
+ Page Should Contain Element xpath=//*[contains(@class,'title')][text()="${product_set_to_check}"]/ancestor::article
+ END
+ END
+
+Yves: view the following Product Set:
+ [Arguments] ${productSetName}
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Click xpath=//*[contains(@class,'product-set-card__name')][text()="${productSetName}"]/ancestor::article
+ ELSE IF '${env}' in ['ui_suite']
+ Click xpath=//article//*[contains(@class,'box')][contains(.,'${productSetName}')]/ancestor::article
+ ELSE
+ Click xpath=//*[contains(@class,'title')][text()="${productSetName}"]/ancestor::article
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: 'Product Set' page contains the following products:
+ [Arguments] @{product_name_list} ${productName1}=${EMPTY} ${productName2}=${EMPTY} ${productName3}=${EMPTY} ${productName4}=${EMPTY} ${productName5}=${EMPTY} ${productName6}=${EMPTY} ${productName7}=${EMPTY} ${productName8}=${EMPTY} ${productName9}=${EMPTY} ${productName10}=${EMPTY} ${productName11}=${EMPTY} ${productName12}=${EMPTY} ${productName13}=${EMPTY} ${productName14}=${EMPTY} ${productName15}=${EMPTY}
+ ${product_name_list_count}= get length ${product_name_list}
+ FOR ${index} IN RANGE 0 ${product_name_list_count}
+ ${product_name_to_check}= Get From List ${product_name_list} ${index}
+ Page Should Contain Element xpath=//product-item[@data-qa='component product-item']//*[@itemprop='name'][contains(.,'${product_name_to_check}')]
+ END
+
+Yves: change variant of the product on CMS page on:
+ [Arguments] ${productName} ${variantToSet}
+ IF '${env}' in ['ui_suite']
+ Set Browser Timeout 1s
+ Run Keyword And Ignore Error Select From List By Value xpath=//product-item//a//*[@itemprop='name'][contains(.,'${productName}')]/ancestor::product-item//select ${variantToSet}
+ Set Browser Timeout ${browser_timeout}
+ ELSE
+ Mouse Over xpath=//*[contains(@class,'product-item__container') and descendant::a[contains(.,'${productName}')]]
+ Click xpath=//*[contains(@class,'product-item__container') and descendant::a[contains(.,'${productName}')]]/ancestor::product-item//span[contains(@class,'selection--single')]
+ Wait Until Element Is Visible xpath=//span[contains(@class,'select2-results')]//li[contains(text(),'${variantToSet}')]
+ Click xpath=//span[contains(@class,'select2-results')]//li[contains(text(),'${variantToSet}')]
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: add all products to the shopping cart from Product Set
+ Wait Until Element Is Enabled ${add_all_product_to_the_shopping_cart}
+ Click ${add_all_product_to_the_shopping_cart}
+ Yves: remove flash messages
+
+Zed: create new product set:
+ [Arguments] @{args}
+ Zed: go to URL: /product-set-gui
+ Zed: click button in Header: Create Product Set
+ Wait Until Element Is Visible ${zed_product_set_name_en_field}
+ ${setData}= Set Up Keyword Arguments @{args}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_set_general_second_locale_expanded_section} timeout=3s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_set_general_second_locale_collapsed_section}
+ Click ${zed_product_set_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{setData}
+ ${key}= Convert To Lower Case ${key}
+ IF '${key}'=='name en' and '${value}' != '${EMPTY}' Type Text ${zed_product_set_name_en_field} ${value}
+ IF '${key}'=='name de' and '${value}' != '${EMPTY}' Type Text ${zed_product_set_name_de_field} ${value}
+ IF '${key}'=='url en' and '${value}' != '${EMPTY}' Type Text ${zed_product_set_url_en_field} ${value}
+ IF '${key}'=='url de' and '${value}' != '${EMPTY}' Type Text ${zed_product_set_url_de_field} ${value}
+ IF '${key}'=='set key' and '${value}' != '${EMPTY}' Type Text ${zed_product_set_key_field} ${value}
+ IF '${key}'=='active' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox ${zed_product_set_is_active_checkbox}
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox ${zed_product_set_is_active_checkbox}
+ END
+ END
+ IF '${key}'=='product' and '${value}' != '${EMPTY}'
+ Zed: switch to tab in product set: Products
+ Wait Until Element Is Visible ${zed_product_set_search_product_table_field}
+ Input Text ${zed_product_set_search_product_table_field} ${value}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 3s
+ Check Checkbox ${zed_product_set_search_product_table_select_first_checkbox}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ IF '${key}'=='product 2' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_set_search_product_table_field}
+ Input Text ${zed_product_set_search_product_table_field} ${value}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 3s
+ Check Checkbox ${zed_product_set_search_product_table_select_first_checkbox}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ IF '${key}'=='product 3' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_set_search_product_table_field}
+ Input Text ${zed_product_set_search_product_table_field} ${value}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 3s
+ Check Checkbox ${zed_product_set_search_product_table_select_first_checkbox}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ END
+ Zed: submit the form
+ Wait Until Element Is Not Visible ${zed_save_button}
+ Trigger multistore p&s
+
+Zed: switch to tab in product set:
+ [Arguments] ${tab_name}
+ Click xpath=//form[@name='product_set_form']//div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-tab-content-id]//a[contains(.,'${tab_name}')]
+
+Zed: delete product set:
+ [Arguments] ${set_name}
+ Zed: go to URL: /product-set-gui
+ Zed: click Action Button in a table for row that contains: ${set_name} Delete
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/products_steps.robot b/atest/testdata/performance/resources/steps/products_steps.robot
new file mode 100644
index 0000000..046c534
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/products_steps.robot
@@ -0,0 +1,652 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_edit_product_page.robot
+Resource ../pages/zed/zed_view_abstract_product_page.robot
+Resource ../pages/zed/zed_view_concrete_product_page.robot
+
+*** Keywords ***
+Zed: discontinue the following product:
+ [Arguments] ${productAbstract} ${productConcrete}
+ Wait Until Element Is Visible ${zed_log_out_button}
+ Zed: go to URL: /product-management
+ Zed: perform search by: ${productAbstract}
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: perform search by: ${productAbstract}
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: variants
+ Zed: click Action Button in Variant table for row that contains: ${productConcrete} Edit
+ Wait Until Element Is Visible ${zed_pdp_concrete_main_content_locator}
+ Zed: go to tab by link href that contains: discontinue
+ ${can_be_discontinued}= Run Keyword And Return Status Page Should Contain Element ${zed_pdp_discontinue_button}
+ IF '${can_be_discontinued}'=='True' Click ${zed_pdp_discontinue_button}
+
+Zed: undo discontinue the following product:
+ [Arguments] ${productAbstract} ${productConcrete}
+ Zed: go to URL: /product-management
+ Zed: perform search by: ${productAbstract}
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: perform search by: ${productAbstract}
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: variants
+ Zed: click Action Button in Variant table for row that contains: ${productConcrete} Edit
+ Wait Until Element Is Visible ${zed_pdp_concrete_main_content_locator}
+ Zed: go to tab by link href that contains: discontinue
+ ${can_be_restored}= Run Keyword And Return Status Page Should Contain Element ${zed_pdp_restore_button}
+ IF '${can_be_restored}'=='True' Click ${zed_pdp_restore_button}
+
+Zed: check if at least one price exists for concrete and add if doesn't:
+ [Arguments] ${price}
+ ${currentURL}= Get Location
+ IF 'content-price' not in '${currentURL}' Zed: go to tab by link href that contains: content-price
+ ${exists}= Run Keyword And Return Status Page Should Contain Element xpath=//table[@id='price-table-collection']//input[@id='product_concrete_form_edit_prices_1-93-DEFAULT-BOTH_moneyValue_gross_amount']
+ IF '${exists}'=='False' Type Text xpath=//table[@id='price-table-collection']//input[@id='product_concrete_form_edit_prices_1-93-DEFAULT-BOTH_moneyValue_gross_amount'] ${price}
+ Click ${zed_pdp_save_button}
+
+Zed: change concrete product price on:
+ [Arguments] @{args}
+ ${priceData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: variants
+ Zed: click Action Button in Variant table for row that contains: ${productConcrete} Edit
+ Wait Until Element Is Visible ${zed_pdp_concrete_main_content_locator}
+ Zed: go to tab by link href that contains: content-price
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ ${store}= Set Variable ${value}
+ END
+ IF '${key}'=='mode' and '${value}' != '${EMPTY}'
+ ${mode}= Set Variable ${value}_amount
+ END
+ IF '${key}'=='type' and '${value}' == 'default'
+ ${type}= Set Variable DEFAULT
+ END
+ IF '${key}'=='type' and '${value}' == 'original'
+ ${type}= Set Variable ORIGINAL
+ END
+ IF '${key}'=='currency' and '${value}' == '€'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/../following-sibling::tr[1]//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='currency' and '${value}' == 'CHF'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/ancestor::tr//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='amount' and '${value}' != '${EMPTY}'
+ Type Text ${inputField} ${value}
+ END
+ END
+ Sleep 1s
+ Click ${zed_pdp_save_button}
+ ### resave to apply changes
+ Set Browser Timeout 1s
+ TRY
+ Click ${zed_pdp_save_button}
+ EXCEPT
+ Log Form is already submitted
+ END
+ Set Browser Timeout ${browser_timeout}
+ ${is_success_message_displayed}= Run Keyword And Ignore Error Element Should Be Visible ${zed_success_flash_message} timeout=1s
+ IF 'FAIL' in $is_success_message_displayed
+ Trigger multistore p&s
+ Reload
+ Sleep 1s
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ ${store}= Set Variable ${value}
+ END
+ IF '${key}'=='mode' and '${value}' != '${EMPTY}'
+ ${mode}= Set Variable ${value}_amount
+ END
+ IF '${key}'=='type' and '${value}' == 'default'
+ ${type}= Set Variable DEFAULT
+ END
+ IF '${key}'=='type' and '${value}' == 'original'
+ ${type}= Set Variable ORIGINAL
+ END
+ IF '${key}'=='currency' and '${value}' == '€'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/../following-sibling::tr[1]//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='currency' and '${value}' == 'CHF'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/ancestor::tr//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='amount' and '${value}' != '${EMPTY}'
+ Type Text ${inputField} ${value}
+ END
+ END
+ Sleep 1s
+ Click ${zed_pdp_save_button}
+ END
+ Page Should Contain Element ${zed_success_flash_message}
+
+Zed: add following alternative products to the concrete:
+ [Arguments] @{alternative_products_list}
+ ${currentURL}= Get Location
+ IF 'content-alternatives' not in '${currentURL}' Zed: go to tab by link href that contains: alternatives
+ ${alternative_products_list_count}= get length ${alternative_products_list}
+ FOR ${index} IN RANGE 0 ${alternative_products_list_count}
+ ${alternative_product_to_assign}= Get From List ${alternative_products_list} ${index}
+ Type Text ${zed_pdp_add_products_alternative_input} ${alternative_product_to_assign}
+ Wait Until Element Is Visible ${zed_pdp_alternative_products_suggestion}
+ Click xpath=//ul[@id='select2-product_concrete_form_edit_alternative_products-results']/li[contains(@class,'select2-results__option') and contains(text(),'(sku: ${alternative_product_to_assign})')]
+ END
+ Zed: submit the form
+
+Zed: concrete product has the following alternative products:
+ [Arguments] @{alternative_products_list}
+ ${currentURL}= Get Location
+ IF 'content-alternatives' not in '${currentURL}' Zed: go to tab by link href that contains: alternatives
+ ${alternative_products_list_count}= get length ${alternative_products_list}
+ FOR ${index} IN RANGE 0 ${alternative_products_list_count}
+ ${alternative_product_to_check}= Get From List ${alternative_products_list} ${index}
+ Wait Until Element Is Visible xpath=//div[@id='tab-content-alternatives']//table/tbody
+ Table Should Contain xpath=//div[@id='tab-content-alternatives']//table/tbody ${alternative_product_to_check}
+ END
+
+Zed: switch to the tab on 'Edit product' page:
+ [Arguments] ${tabToUse}
+ Click xpath=//form[contains(@name,'form_edit')]/div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='${tabToUse}']
+
+Zed: switch to the tab on 'Add product' page:
+ [Arguments] ${tabToUse}
+ Click xpath=//form[contains(@name,'form_add')]/div[@class='tabs-container']/ul[contains(@class,'nav-tabs')]//li[@data-bs-toggle='tab']//*[text()='${tabToUse}']
+
+Zed: product is successfully discontinued
+ ${currentURL}= Get Location
+ IF 'discontinue' not in '${currentURL}' Zed: go to tab by link href that contains: discontinue
+ Page Should Contain Element ${zed_pdp_restore_button}
+
+Zed: view product page is displayed
+ Wait Until Element Is Visible ${zed_view_abstract_product_main_content_locator}
+
+Zed: view abstract product page contains:
+ [Arguments] @{args}
+ ${abstractProductData}= Set Up Keyword Arguments @{args}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_view_abstract_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_view_abstract_general_second_locale_collapsed_section}
+ Click ${zed_view_abstract_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{abstractProductData}
+ IF '${key}'=='merchant' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_abstract_product_merchant} ${value}
+ END
+ IF '${key}'=='status' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_abstract_product_status} ${value}
+ END
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_abstract_product_store}[${env}] ${value}
+ END
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_abstract_product_sku}[${env}] ${value}
+ END
+ IF '${key}'=='name' and '${value}' != '${EMPTY}'
+ Element Should Contain ${zed_view_abstract_product_name}[${env}] ${value}
+ END
+ IF '${key}'=='variants count' and '${value}' != '${EMPTY}'
+ Clear Text xpath=//div[@id='product-variant-table_filter']//input[@type='search']
+ Wait Until Element Is Visible xpath=//table[@id='product-variant-table']//tbody/tr[1]
+ ${actualVariantsCount}= Get Element Count xpath=//table[@id='product-variant-table']//tbody/tr
+ Should Be Equal '${actualVariantsCount}' '${value}'
+ END
+ END
+
+Zed: update abstract product data:
+ [Arguments] @{args}
+ ${abstractProductData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ TRY
+ Page Should Contain Element ${zed_pdp_save_button}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ Page Should Contain Element ${zed_pdp_save_button}
+ END
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} 100ms
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{abstractProductData}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='unselect store' and '${value}' != '${EMPTY}'
+ Zed: Uncheck Checkbox by Label: ${value}
+ END
+ IF '${key}'=='name en' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_edit_name_en_input}
+ Type Text ${zed_product_edit_name_en_input} ${value}
+ END
+ IF '${key}'=='name de' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_edit_name_de_input}
+ Type Text ${zed_product_edit_name_de_input} ${value}
+ END
+ IF '${key}'=='new from' and '${value}' != '${EMPTY}'
+ Type Text ${zed_product_edit_new_from} ${value}
+ Keyboard Key press Enter
+ END
+ IF '${key}'=='new to' and '${value}' != '${EMPTY}'
+ Type Text ${zed_product_edit_new_to} ${value}
+ Keyboard Key press Enter
+ END
+ END
+ Click ${zed_pdp_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Load event was not fired
+ END
+
+Zed: update abstract product price on:
+ [Arguments] @{args}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Load event was not fired
+ END
+ ${priceData}= Set Up Keyword Arguments @{args}
+ ${productAbstractIsProvided}= Run Keyword And Return Status Variable Should Exist ${productAbstract}
+ Disable Automatic Screenshots on Failure
+ ${is_edit_abstract_price_tab_exists}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(@data-bs-toggle,'tab')][contains(@data-bs-target,'content-price_and_tax')] | //*[contains(@data-bs-toggle,'tab')]//*[contains(@data-bs-target,'content-price_and_tax')] timeout=100ms
+ Restore Automatic Screenshots on Failure
+ IF '${is_edit_abstract_price_tab_exists}'=='False' and ${productAbstractIsProvided}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: content-price
+ ELSE
+ ${currentURL}= Get Location
+ IF 'content-price_and_tax' not in '${currentURL}'
+ Zed: go to tab by link href that contains: content-price_and_tax
+ END
+ END
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ ${store}= Set Variable ${value}
+ END
+ IF '${key}'=='mode' and '${value}' != '${EMPTY}'
+ ${mode}= Set Variable ${value}_amount
+ END
+ IF '${key}'=='type' and '${value}' == 'default'
+ ${type}= Set Variable DEFAULT
+ END
+ IF '${key}'=='type' and '${value}' == 'original'
+ ${type}= Set Variable ORIGINAL
+ END
+ IF '${key}'=='currency' and '${value}' == '€'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/../following-sibling::tr[1]//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='currency' and '${value}' == 'CHF'
+ ${inputField}= Set Variable xpath=//table[@id='price-table-collection']//td[1][contains(text(),'${store}')]/ancestor::tr//input[contains(@id,'${mode}')][contains(@id,'${type}')]
+ END
+ IF '${key}'=='amount' and '${value}' != '${EMPTY}'
+ Type Text ${inputField} ${value}
+ END
+ IF '${key}'=='tax set' and '${value}' != '${EMPTY}' Select From List By Label ${zed_product_tax_set_select} ${value}
+ END
+ Click and retry if 5xx occurred: ${zed_pdp_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Load event was not fired
+ END
+
+Zed: start new abstract product creation:
+ [Arguments] @{args}
+ ${abstractProductData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click button in Header: Create Product
+ TRY
+ Page Should Contain Element ${zed_pdp_save_button}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click button in Header: Create Product
+ Page Should Contain Element ${zed_pdp_save_button}
+ END
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{abstractProductData}
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}' Type Text ${zed_product_add_sku_input} ${value}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='unselect store' and '${value}' != '${EMPTY}'
+ Zed: Uncheck Checkbox by Label: ${value}
+ END
+ IF '${key}'=='name en' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_add_name_en_input}
+ Type Text ${zed_product_add_name_en_input} ${value}
+ END
+ IF '${key}'=='name de' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_product_add_name_de_input}
+ Type Text ${zed_product_add_name_de_input} ${value}
+ END
+ IF '${key}'=='new from' and '${value}' != '${EMPTY}'
+ Type Text ${zed_product_add_new_from} ${value}
+ Keyboard Key press Enter
+ END
+ IF '${key}'=='new to' and '${value}' != '${EMPTY}'
+ Type Text ${zed_product_add_new_to} ${value}
+ Keyboard Key press Enter
+ END
+ END
+ Click ${zed_pdp_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Load event was not fired
+ END
+
+Zed: select abstract product variants:
+ [Arguments] @{args}
+ ${abstractProductData}= Set Up Keyword Arguments @{args}
+ Zed: go to tab by link href that contains: variants
+ FOR ${key} ${value} IN &{abstractProductData}
+ IF '${key}'=='attribute 1' and '${value}' != '${EMPTY}'
+ ${attribute_1}= Set Variable ${value}
+ END
+ IF '${key}'=='attribute value 1' and '${value}' != '${EMPTY}'
+ Check Checkbox xpath=//input[@id='product_form_add_attribute_super_${attribute_1}_name']
+ Click xpath=//input[@id='product_form_add_attribute_super_${attribute_1}_name']/ancestor::div[contains(@class,'input-group')]//span[@role='combobox']
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ END
+ IF '${key}'=='attribute 2' and '${value}' != '${EMPTY}'
+ ${attribute_2}= Set Variable ${value}
+ END
+ IF '${key}'=='attribute value 2' and '${value}' != '${EMPTY}'
+ Check Checkbox xpath=//input[@id='product_form_add_attribute_super_${attribute_2}_name']
+ Click xpath=//input[@id='product_form_add_attribute_super_${attribute_2}_name']/ancestor::div[contains(@class,'input-group')]//span[@role='combobox']
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ END
+ IF '${key}'=='attribute 3' and '${value}' != '${EMPTY}'
+ ${attribute_1}= Set Variable ${value}
+ END
+ IF '${key}'=='attribute value 3' and '${value}' != '${EMPTY}'
+ Check Checkbox xpath=//input[@id='product_form_add_attribute_super_${attribute_3}_name']
+ Click xpath=//input[@id='product_form_add_attribute_super_${attribute_3}_name']/ancestor::div[contains(@class,'input-group')]//span[@role='combobox']
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_form_add_attribute_super')][contains(text(),'${value}')]
+ END
+ END
+ Click ${zed_pdp_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Load event was not fired
+ END
+
+Zed: change concrete product data:
+ [Arguments] @{args}
+ ${priceData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: variants
+ Zed: click Action Button in Variant table for row that contains: ${productConcrete} Edit
+ Wait Until Element Is Visible ${zed_pdp_concrete_main_content_locator}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{priceData}
+ IF '${key}'=='name en' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_pdp_concrete_name_en_input}
+ Type Text ${zed_pdp_concrete_name_en_input} ${value}
+ END
+ IF '${key}'=='name de' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_pdp_concrete_name_de_input}
+ Type Text ${zed_pdp_concrete_name_de_input} ${value}
+ END
+ IF '${key}'=='active' and '${value}' != '${EMPTY}'
+ Disable Automatic Screenshots on Failure
+ ${is_active}= Run Keyword And Return Status Page Should Contain Element xpath=//div[@class='title-action']/a[contains(.,'Activate')] timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${is_active}'=='True' and '${value}'=='true'
+ Zed: click button in Header: Activate
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ END
+ IF '${is_active}'=='False' and '${value}'=='false'
+ Zed: click button in Header: Deactivate
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ END
+ END
+ IF '${key}'=='searchable en' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox ${zed_pdp_concrete_searchable_en}
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox ${zed_pdp_concrete_searchable_en}
+ END
+ END
+ IF '${key}'=='searchable de' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox ${zed_pdp_concrete_searchable_de}
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox ${zed_pdp_concrete_searchable_de}
+ END
+ END
+ END
+ Click ${zed_pdp_save_button}
+
+Zed: change concrete product stock:
+ [Arguments] @{args}
+ ${stockData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: go to tab by link href that contains: variants
+ Zed: click Action Button in Variant table for row that contains: ${productConcrete} Edit
+ Wait Until Element Is Visible ${zed_pdp_concrete_main_content_locator}
+ Zed: go to tab by link href that contains: content-price
+ FOR ${key} ${value} IN &{stockData}
+ IF '${key}'=='warehouse n1' and '${value}' != '${EMPTY}'
+ ${warehouse1}= Set Variable ${value}
+ END
+ IF '${key}'=='warehouse n2' and '${value}' != '${EMPTY}'
+ ${warehouse2}= Set Variable ${value}
+ END
+ IF '${key}'=='warehouse n3' and '${value}' != '${EMPTY}'
+ ${warehouse3}= Set Variable ${value}
+ END
+ IF '${key}'=='warehouse n4' and '${value}' != '${EMPTY}'
+ ${warehouse4}= Set Variable ${value}
+ END
+ IF '${key}'=='warehouse n5' and '${value}' != '${EMPTY}'
+ ${warehouse5}= Set Variable ${value}
+ END
+ IF '${key}'=='warehouse n1 qty' and '${value}' != '${EMPTY}' Type Text xpath=//*[@id="tab-content-price"]//input[@value='${warehouse1}']/../following-sibling::div[1]//input[@id] ${value}
+ IF '${key}'=='warehouse n2 qty' and '${value}' != '${EMPTY}' Type Text xpath=//*[@id="tab-content-price"]//input[@value='${warehouse2}']/../following-sibling::div[1]//input[@id] ${value}
+ IF '${key}'=='warehouse n3 qty' and '${value}' != '${EMPTY}' Type Text xpath=//*[@id="tab-content-price"]//input[@value='${warehouse3}']/../following-sibling::div[1]//input[@id] ${value}
+ IF '${key}'=='warehouse n4 qty' and '${value}' != '${EMPTY}' Type Text xpath=//*[@id="tab-content-price"]//input[@value='${warehouse4}']/../following-sibling::div[1]//input[@id] ${value}
+ IF '${key}'=='warehouse n5 qty' and '${value}' != '${EMPTY}' Type Text xpath=//*[@id="tab-content-price"]//input[@value='${warehouse5}']/../following-sibling::div[1]//input[@id] ${value}
+ IF '${key}'=='warehouse n1 never out of stock' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse1}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse1}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ END
+ IF '${key}'=='warehouse n2 never out of stock' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse2}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse2}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ END
+ IF '${key}'=='warehouse n3 never out of stock' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse3}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse3}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ END
+ IF '${key}'=='warehouse n4 never out of stock' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse4}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse4}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ END
+ IF '${key}'=='warehouse n5 never out of stock' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse5}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox xpath=//*[@id="tab-content-price"]//input[@value='${warehouse5}']/../following-sibling::div[2]//input[@type='checkbox']
+ END
+ END
+ END
+ Click ${zed_pdp_save_button}
+
+Zed: add new concrete product to abstract:
+ [Arguments] @{args}
+ ${productData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ TRY
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ EXCEPT
+ Zed: go to URL: /product-management
+ Zed: click Action Button in a table for row that contains: ${productAbstract} Edit
+ END
+ Wait Until Element Is Visible ${zed_pdp_abstract_main_content_locator}
+ Zed: click button in Header: Add Variant
+ Wait Until Element Is Visible ${zed_pdp_add_concrete_main_content_locator}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Page Should Contain Element ${zed_product_general_second_locale_expanded_section} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_product_general_second_locale_collapsed_section}
+ Click ${zed_product_general_second_locale_collapsed_section}
+ END
+ FOR ${key} ${value} IN &{productData}
+ IF '${key}'=='sku' and '${value}' != '${EMPTY}' Type Text ${zed_add_concrete_sku_field} ${value}
+ IF '${key}'=='autogenerate sku' and '${value}' != '${EMPTY}'
+ IF '${value}'=='true'
+ Check Checkbox ${zed_add_concrete_autogenerate_sku}
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox ${zed_add_concrete_autogenerate_sku}
+ END
+ END
+ IF '${key}'=='attribute 1' and '${value}' != '${EMPTY}'
+ Click (//span[@class='select2-selection select2-selection--single'])[1]
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ END
+ IF '${key}'=='attribute 2' and '${value}' != '${EMPTY}'
+ Click (//span[@class='select2-selection select2-selection--single'])[2]
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ END
+ IF '${key}'=='attribute 3' and '${value}' != '${EMPTY}'
+ Click (//span[@class='select2-selection select2-selection--single'])[3]
+ Wait Until Element Is Visible xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ Click xpath=//li[contains(@id,'select2-product_concrete_form_add_container_product_concrete_super_attributes_form_product_concrete_super_attributes')][contains(@id,'${value}')]
+ END
+ IF '${key}'=='name en' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_add_concrete_name_en_input}
+ Type Text ${zed_add_concrete_name_en_input} ${value}
+ END
+ IF '${key}'=='name de' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_add_concrete_name_de_input}
+ Type Text ${zed_add_concrete_name_de_input} ${value}
+ END
+ IF '${key}'=='use prices from abstract' and '${value}' != '${EMPTY}'
+ Zed: go to tab by link href that contains: content-price
+ Wait Until Element Is Visible ${zed_add_concrete_use_price_from_abstract}
+ IF '${value}'=='true'
+ Check Checkbox ${zed_add_concrete_use_price_from_abstract}
+ END
+ IF '${value}'=='false'
+ Uncheck Checkbox ${zed_add_concrete_use_price_from_abstract}
+ END
+ END
+ END
+ Click ${zed_pdp_save_button}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/push_notifications_steps.robot b/atest/testdata/performance/resources/steps/push_notifications_steps.robot
new file mode 100644
index 0000000..618c58d
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/push_notifications_steps.robot
@@ -0,0 +1,96 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Create warehouse in DB:
+ [Documentation] This keyword creates a new entry in the DB table `spy_stock`.
+ ... *Example:*
+ ...
+ ... ``Create warehouse in DB name=Test isActive=true warehouseUuid=262feb9d-33a7-5c55-9b04-45b1fd22067e``
+ ...
+ [Arguments] ${name}=${None} ${isActive}=${True} ${warehouseUuid}=${None}
+ IF '${name}' == '${None}'
+ ${name}= Generate Random String 5 [LETTERS]
+ END
+ IF '${warehouseUuid}' == '${None}'
+ ${uuid}= Evaluate uuid.uuid4()
+ END
+ ${idStock}= Get next id from table spy_stock id_stock
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String INSERT IGNORE INTO spy_stock(name, uuid, is_active) VALUES ('${name}', '${warehouseUuid}', ${isActive});
+ ELSE
+ Execute Sql String INSERT INTO spy_stock(id_stock, name, uuid, is_active) VALUES (${idStock}, '${name}', '${warehouseUuid}', ${isActive});
+ END
+ Disconnect From Database
+
+Assign user to Warehouse in DB:
+ [Documentation] This keyword assigns provided user to a warehouse and makes user a warehouse-user.
+ ...
+ ... It gets the UUID for the specified user ``${email}`` and ``${warehouseUuid}`` and saves it into spy_warehouse_user_assignment.
+ ... Also it updates `spy_user.is_warehouse_user` to true for specified user.
+ ...
+ ... *Example:*
+ ...
+ ... ``Assign user to Warehouse in DB: richard@spryker.com 834b3731-02d4-5d6f-9a61-d63ae5e70517``
+ [Arguments] ${email} ${warehouse_uuid}
+ Connect to Spryker DB
+ ${user_uuid}= Query SELECT uuid FROM spy_user WHERE username = '${email}' LIMIT 1
+ ${fk_warehouse}= Query SELECT id_stock FROM spy_stock WHERE uuid = '${warehouse_uuid}' LIMIT 1
+ Disconnect From Database
+ ${idWarehouseUserAssignment}= Get next id from table spy_warehouse_user_assignment id_warehouse_user_assignment
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String INSERT IGNORE INTO spy_warehouse_user_assignment (`uuid`, fk_warehouse, user_uuid, is_active) VALUE ('random_uuid', ${fk_warehouse[0][0]}, '${user_uuid[0][0]}', 1);
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = 1 WHERE username = '${email}';
+ ELSE
+ Execute Sql String INSERT INTO spy_warehouse_user_assignment (id_warehouse_user_assignment, uuid, fk_warehouse, user_uuid, is_active) VALUES (${idWarehouseUserAssignment}, 'random_uuid', ${fk_warehouse[0][0]}, '${user_uuid[0][0]}', true);
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = true WHERE username = '${email}';
+ END
+ Disconnect From Database
+
+De-assign user from Warehouse in DB:
+ [Documentation] This keyword de-assigns provided user from a warehouse and unmakes user a warehouse-user.
+ ...
+ ... It gets the UUID for the specified user ``${email}`` and ``${warehouseUuid}`` and removes it from spy_warehouse_user_assignment.
+ ... Also it updates `spy_user.is_warehouse_user` to false for specified user.
+ ...
+ ... *Example:*
+ ...
+ ... ``De-assign user from Warehouse in DB: richard@spryker.com 834b3731-02d4-5d6f-9a61-d63ae5e70517``
+ [Arguments] ${email} ${warehouse_uuid}
+ Connect to Spryker DB
+ ${user_uuid} Query SELECT uuid FROM spy_user WHERE username = '${email}' LIMIT 1;
+ ${fk_warehouse} Query SELECT id_stock FROM spy_stock WHERE uuid = '${warehouse_uuid}' LIMIT 1;
+ Execute Sql String DELETE FROM spy_warehouse_user_assignment WHERE user_uuid = '${user_uuid[0][0]}' AND fk_warehouse = ${fk_warehouse[0][0]};
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = 0 WHERE username = '${email}';
+ ELSE
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = false WHERE username = '${email}';
+ END
+ Disconnect From Database
+
+Delete warehouse in DB:
+ [Documentation] This keyword deletes the entry from the DB table `spy_stock`.
+ ... *Example:*
+ ...
+ ... ``Delete warehouse in DB 834b3731-02d4-5d6f-9a61-d63ae5e70517``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_stock WHERE uuid = '${uuid}';
+ Disconnect From Database
+
+Delete push notification subscription in DB:
+ [Documentation] This keyword deletes the entry from the DB table `spy_push_notification_subscription`.
+ ... *Example:*
+ ...
+ ... ``Delete push notification subscription in DB 834b3731-02d4-5d6f-9a61-d63ae5e70517``
+ ...
+ [Arguments] ${uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_push_notification_subscription WHERE uuid = '${uuid}';
+ Disconnect From Database
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/quick_order_steps.robot b/atest/testdata/performance/resources/steps/quick_order_steps.robot
new file mode 100644
index 0000000..d007d9a
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/quick_order_steps.robot
@@ -0,0 +1,82 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../common/common_yves.robot
+Resource ../pages/yves/yves_quick_order_page.robot
+
+*** Keywords ***
+Yves: go to 'Quick Order' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/quick-order
+
+Yves: add the following articles into the form through quick order text area:
+ [Arguments] ${contentToUse}
+ Clear Text ${quick_order_add_articles_text_area}
+ Type Text ${quick_order_add_articles_text_area} ${contentToUse}
+ Click ${quick_order_verify_button}
+
+Yves: add products to the shopping cart from quick order page
+ Click ${quick_order_add_to_cart_button}
+ Yves: remove flash messages
+
+Yves: add products to the shopping list from quick order page with name:
+ [Arguments] ${shoppingListName}
+ Wait Until Element Is Visible ${quick_order_shopping_list_selector}
+ Yves: Select shopping list on 'Quick Order' page ${shoppingListName}
+ Click ${quick_order_add_to_shopping_list_button}
+ Yves: remove flash messages
+
+Yves: Select shopping list on 'Quick Order' page
+ [Arguments] ${shoppingListName}
+ Scroll Element Into View ${quick_order_shopping_list_selector}
+ Select From List By Label ${quick_order_shopping_list_selector} ${shoppingListName}
+
+Yves: find and add new item in the quick order form:
+ [Arguments] @{args}
+ ${quickOrderData}= Set Up Keyword Arguments @{args}
+ Clear Text ${quick_order_add_articles_text_area}
+ Type Text ${quick_order_add_articles_text_area} ${EMPTY}
+ Sleep 3s
+ Click ${quick_order_verify_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Disable Automatic Screenshots on Failure
+ ${emptyRowAvailable}= Run Keyword And Return Status Page Should Contain Element ${quick_order_first_empty_row}
+ Restore Automatic Screenshots on Failure
+ IF '${emptyRowAvailable}'=='False'
+ Click ${quick_order_add_more_rows}
+ Wait Until Element Is Visible ${quick_order_first_empty_row}
+ END
+ Type Text ${quick_order_first_empty_row} ${searchQuery}
+ Wait Until Element Is Visible ${quick_order_row_search_results}
+ Wait Until Page Contains Element xpath=(//div[contains(@data-qa,'component quick-order-rows')]//*[contains(@class,'autocomplete')][@value=''])[1]/ancestor::quick-order-row//ul[@data-qa='component products-list']/li[@data-value='${searchQuery}']
+ Click xpath=(//div[contains(@data-qa,'component quick-order-rows')]//*[contains(@class,'autocomplete')][@value=''])[1]/ancestor::quick-order-row//ul[@data-qa='component products-list']/li[@data-value='${searchQuery}']
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 3s
+ Wait Until Element Is Visible ${quick_order_row_merchant_selector}
+ Select From List By Label ${quick_order_row_merchant_selector} ${merchant}
+ Sleep 1s
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Clear Text ${quick_order_add_articles_text_area}
+ Type Text ${quick_order_add_articles_text_area} ${EMPTY}
+ Sleep 1s
+ Click ${quick_order_verify_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Repeat Keyword 3 Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/request_for_quote_steps.robot b/atest/testdata/performance/resources/steps/request_for_quote_steps.robot
new file mode 100644
index 0000000..919b671
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/request_for_quote_steps.robot
@@ -0,0 +1,171 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../pages/yves/yves_quote_request_page.robot
+Resource ../common/common_yves.robot
+Resource ../steps/header_steps.robot
+Resource ../common/common.robot
+Resource ../../resources/pages/yves/yves_shopping_cart_page.robot
+
+*** Keywords ***
+Yves: go to 'Agent Quote Requests' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/agent/quote-request
+
+Yves: go to 'Quote Requests' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/quote-request
+
+Yves: convert a cart to a quote request
+ Click ${request_a_quote_button}
+ Click ${quote_request_convert_from_cart_confirm_button}
+
+Yves: quote request with reference xxx should have status:
+ [Arguments] ${quoteReference} ${expectedStatus}
+ Page Should Contain Element xpath=//div[contains(@data-qa,'component quote-request')]//td[contains(.,'${quoteReference}')]
+ ${actualStatus}= Get Text xpath=//div[contains(@data-qa,'component quote-request')]//td[contains(.,'${quoteReference}')]/..//*[contains(@class,'request-status')]
+ Should Be Equal ${expectedStatus} ${actualStatus}
+
+Yves: view quote request with reference:
+ [Arguments] ${quoteReference}
+ IF '${env}' in ['ui_suite']
+ Click xpath=(//div[contains(@data-qa,'component quote-request')]//td[contains(.,'${quoteReference}')]/ancestor::tr/td[last()]//a[contains(@href,'details')])[1]
+ ELSE
+ Click xpath=//div[contains(@data-qa,'component quote-request')]//td[contains(.,'${quoteReference}')]/..//*[text()='View']/ancestor::a[contains(@class,'table-action-link')]
+ END
+
+Yves: click '${buttonName}' button on the 'Quote Request Details' page
+
+ IF '${buttonName}' == 'Back to List'
+ Click ${quote_request_back_to_list_button}
+ ELSE IF '${buttonName}' == 'Cancel'
+ Click ${quote_request_cancel_button}
+ ELSE IF '${buttonName}' == 'Revise'
+ Click ${quote_request_revise_button}
+ ELSE IF '${buttonName}' == 'Convert to Cart'
+ Click ${quote_request_convert_to_cart_button}
+ ELSE IF '${buttonName}' == 'Send to Customer'
+ Click ${quote_request_send_to_customer_button}
+ ELSE IF '${buttonName}' == 'Edit'
+ Click ${quote_request_edit_button}
+ ELSE IF '${buttonName}' == 'Edit Items'
+ Click ${quote_request_edit_items_button}
+ ELSE IF '${buttonName}' == 'Save'
+ Click ${quote_request_save_button}
+ ELSE IF '${buttonName}' == 'Save and Back to Edit'
+ Click ${quote_request_save_and_back_to_edit_button}
+ ELSE IF '${buttonName}' == 'Send to Agent'
+ Click ${quote_request_send_to_agent_button}
+ END
+
+ Yves: remove flash messages
+
+Yves: change price for the product in the quote request with sku xxx on:
+ [Arguments] ${sku} ${priceToSet}
+ Wait Until Element Is Visible ${quote_request_save_button}
+ ${use_default_price_state}= Set Variable ${EMPTY}
+ IF '${env}' in ['ui_suite']
+ Disable Automatic Screenshots on Failure
+ ${use_default_price_state}= Run Keyword And Return Status Page Should Contain Element xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[@type='checkbox'][@checked]
+ Restore Automatic Screenshots on Failure
+ IF '${use_default_price_state}'=='True' Uncheck Checkbox xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[@type='checkbox'] force=True
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ TRY
+ Wait Until Element Is Visible xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[contains(@id,'UnitGrossPrice')] timeout=5s
+ EXCEPT
+ Reload
+ Disable Automatic Screenshots on Failure
+ ${use_default_price_state}= Run Keyword And Return Status Page Should Contain Element xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[@type='checkbox'][@checked]
+ Restore Automatic Screenshots on Failure
+ IF '${use_default_price_state}'=='True' Uncheck Checkbox xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[@type='checkbox'] force=True
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ Wait Until Element Is Visible xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[contains(@id,'UnitGrossPrice')]
+ Type Text xpath=//product-item[contains(@data-qa,'product-cart-item')]//*[@itemprop='sku' and (text()='${sku}' or @content='${sku}')]/ancestor::product-item//input[contains(@id,'UnitGrossPrice')] ${priceToSet}
+ ELSE
+ Disable Automatic Screenshots on Failure
+ ${use_default_price_state}= Run Keyword And Return Status Page Should Contain Element xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//input[@type='checkbox'][@checked]
+ Restore Automatic Screenshots on Failure
+ IF '${use_default_price_state}'=='True' Click xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//span[@data-qa='component checkbox use_default_price']
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ TRY
+ Wait Until Element Is Visible xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//input[@id]//ancestor::div[contains(@id,'quote_request_agent_form')] timeout=5s
+ EXCEPT
+ Reload
+ Disable Automatic Screenshots on Failure
+ ${use_default_price_state}= Run Keyword And Return Status Page Should Contain Element xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//input[@type='checkbox'][@checked]
+ Restore Automatic Screenshots on Failure
+ IF '${use_default_price_state}'=='True' Click xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//span[@data-qa='component checkbox use_default_price']
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Sleep 1s
+ END
+ Wait Until Element Is Visible xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//input[@id]//ancestor::div[contains(@id,'quote_request_agent_form')]
+ Type Text xpath=//article[@data-qa='component quote-request-cart-item']//div[contains(@class,'quote-request-cart-item__column--content')][contains(.,'${sku}')]/ancestor::article//*[contains(@class,'quote-request-cart-item__column--total')]//input[@id] ${priceToSet}
+ END
+
+Yves: add the following note to the quote request:
+ [Arguments] ${noteToSet}
+ Type Text ${quote_request_notes_text_area} ${noteToSet}
+
+Yves: go to the quote request through the header with reference:
+ [Arguments] ${quoteReference}
+ # *** OBSOLETE ***
+ # Yves: move mouse over header menu item: ${quoteRequestsWidget}
+ # Wait Until Element Is Visible ${agent_quote_requests_widget}
+ # Click xpath=//agent-control-bar//a[contains(@href,'quote-request')]/ancestor::li[contains(@class,'menu__item--has-children')]//a[contains(@class,'quote-request-detail')][contains(.,'${quoteReference}')]
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/agent/quote-request/details/${quoteReference}
+
+Yves: 'Quote Request Details' page contains the following note:
+ [Arguments] ${noteToCheck}
+ IF '${env}' in ['ui_suite']
+ ${actualNote}= Get Text xpath=//*[contains(@data-qa,'quote-request-information')]/ancestor::main/div[position()=1]/div[position()=1]//p
+ ELSE
+ ${actualNote}= Get Text xpath=//main[contains(@class,'request-for-quote')]//label[@class='label'][contains(text(),'Notes')]//following-sibling::p[1]
+ END
+ Should Be Equal ${actualNote} ${noteToCheck}
+
+Yves: set 'Valid Till' date for the quote request, today +:
+ [Arguments] ${daysToAdd}
+ ${currentDate}= Get Current Date
+ ${dateToSet}= Add Time To Date ${currentDate} ${daysToAdd}
+ Add/Edit element attribute with JavaScript: //input[@id='quote_request_agent_form_validUntil'] value ${dateToSet}
+
+Yves: set 'Valid Till' date in the past for the quote request:
+ Add/Edit element attribute with JavaScript: //input[@id='quote_request_agent_form_validUntil'] value 2019-07-15 02:47:55.432
+
+Yves: submit new request for quote
+ [Documentation] Returns ID of the RfQ
+ Yves: click on the 'Request a Quote' button in the shopping cart
+ Click ${quote_request_convert_from_cart_confirm_button}
+ IF '${env}' in ['ui_suite']
+ ${lastCreatedRfQ}= Get Text xpath=//*[@data-qa='component breadcrumb']//li[last()]
+ ELSE
+ ${lastCreatedRfQ}= Get Text xpath=//div[@class='page-info']//*[contains(@class,'page-info__title')]
+ END
+ ${lastCreatedRfQ}= Replace String ${lastCreatedRfQ} \# ${EMPTY}
+ ${lastCreatedRfQ}= Replace String ${lastCreatedRfQ} ${SPACE} ${EMPTY}
+ Set Suite Variable ${lastCreatedRfQ} ${lastCreatedRfQ}
+ RETURN ${lastCreatedRfQ}
diff --git a/atest/testdata/performance/resources/steps/shipment_type_steps.robot b/atest/testdata/performance/resources/steps/shipment_type_steps.robot
new file mode 100644
index 0000000..e9b3d44
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/shipment_type_steps.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+Get shipment type id from DB by key:
+ [Documentation] This keyword gets the entry ${id_shipment_type_store[0][0]} from the DB table `spy_shipment_type`.
+ ... *Example:*
+ ...
+ ... ``Get shipment type id from DB by key: some-shipment-type-61152``
+ ...
+ [Arguments] ${key}
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ ${id_shipment_type_store} Query SELECT id_shipment_type FROM spy_shipment_type WHERE `key` = '${key}' ORDER BY id_shipment_type DESC LIMIT 1;
+ Disconnect From Database
+ ELSE
+ ${id_shipment_type_store} Query SELECT id_shipment_type FROM spy_shipment_type WHERE "key" = '${key}' ORDER BY id_shipment_type DESC LIMIT 1;
+ END
+ Disconnect From Database
+ RETURN ${id_shipment_type_store[0][0]}
+
+Delete shipment type in DB:
+ [Documentation] This keyword deletes the entry from the DB table `spy_shipment_type`. If `withRelations=true`, deletes with relations.
+ ... *Example:*
+ ...
+ ... ``Delete shipment type in DB: some-shipment-type-61152 withRelations=true``
+ ...
+ [Arguments] ${key} ${withRelations}=${True}
+ IF ${withRelations}
+ ${id_shipment_type_store}= Get shipment type id from DB by key: ${key}
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String DELETE FROM spy_shipment_type_store WHERE fk_shipment_type = ${id_shipment_type_store};
+ Execute Sql String DELETE FROM spy_shipment_type WHERE `key` = '${key}';
+ ELSE
+ Execute Sql String DELETE FROM spy_shipment_type_store WHERE fk_shipment_type = ${id_shipment_type_store};
+ Execute Sql String DELETE FROM spy_shipment_type WHERE "key" = '${key}';
+ END
+ Disconnect From Database
+ END
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String DELETE FROM spy_shipment_type WHERE `key` = '${key}';
+ ELSE
+ Execute Sql String DELETE FROM spy_shipment_type WHERE "key" = '${key}';
+ END
+ Disconnect From Database
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/shopping_carts_steps.robot b/atest/testdata/performance/resources/steps/shopping_carts_steps.robot
new file mode 100644
index 0000000..5625892
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/shopping_carts_steps.robot
@@ -0,0 +1,485 @@
+*** Settings ***
+Resource ../pages/yves/yves_shopping_carts_page.robot
+Resource ../pages/yves/yves_shopping_cart_page.robot
+Resource ../pages/yves/yves_delete_shopping_cart_page.robot
+Resource ../common/common_yves.robot
+Resource ../common/common.robot
+
+*** Variables ***
+${upSellProducts} ${shopping_cart_upp-sell_products_section}[${env}]
+${lockedCart} ${shopping_cart_locked_cart_form}
+
+*** Keywords ***
+Yves: 'Shopping Carts' widget contains:
+ [Arguments] ${shoppingCartName} ${accessLevel}
+ Wait Until Element Is Visible ${shopping_car_icon_header_menu_item}[${env}]
+ Mouse Over ${shopping_car_icon_header_menu_item}[${env}]
+ Wait Until Element Is Visible ${shopping_cart_sub_navigation_widget}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//header//cart-counter//a[contains(@href,'/cart')]/ancestor::li//ul[contains(@class,'menu')][contains(@class,'wide')]//*[contains(@data-qa,'mini-cart-detail')]//a[contains(.,'${shoppingCartName}')]/ancestor::div[1]//*[@class='cart-permission'][contains(.,'${accessLevel}')] | //header//cart-counter//a[contains(@href,'/cart')]/ancestor::li//ul[contains(@class,'menu')][contains(@class,'wide')]//*[contains(@data-qa,'mini-cart-detail')]//button[contains(.,'${shoppingCartName}')]/ancestor::div[1]//*[@class='cart-permission'][contains(.,'${accessLevel}')]
+ ELSE
+ Page Should Contain Element xpath=//*[contains(@class,'icon--cart')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-cart')]//span[text()[contains(.,'${accessLevel}')]]/ancestor::div[@class='mini-cart-detail']//*[contains(@class,'mini-cart-detail__title')]/*[text()='${shoppingCartName}']
+ END
+
+Yves: go to 'Shopping Carts' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/multi-cart
+
+Yves: create new 'Shopping Cart' with name:
+ [Arguments] ${shoppingCartName}
+ ${currentURL}= Get Location
+ IF '/multi-cart' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}multi-cart
+ ELSE
+ Go To ${yves_url}multi-cart
+ END
+ END
+ Click ${create_shopping_cart_button}
+ Type Text ${shopping_cart_name_input_field} ${shoppingCartName}
+ Click ${create_new_cart_submit_button}
+
+Yves: the following shopping cart is shown:
+ [Arguments] ${shoppingCartName} ${shoppingCartAccess}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//*[contains(@data-qa,'quote-table')]//*[@class='cart-permission'][contains(.,'${shoppingCartAccess}')]/ancestor::tr/td[1][contains(.,'${shoppingCartName}')]
+ ELSE
+ Page Should Contain Element xpath=//*[@data-qa='component quote-table']//table//td[@data-content='Access'][contains(.,'${shoppingCartAccess}')]/../td[@data-content='Name'][contains(.,'${shoppingCartName}')]
+ END
+Yves: share shopping cart with user:
+ [Arguments] ${shoppingCartName} ${customerToShare} ${accessLevel}
+ Share shopping cart with name: ${shoppingCartName}
+ Select access level to share shopping cart with: ${customerToShare} ${accessLevel}
+ Click ${share_shopping_cart_confirm_button}
+ Yves: 'Shopping Carts' page is displayed
+ Yves: flash message 'should' be shown
+
+Yves: go to the shopping cart through the header with name:
+ [Arguments] ${shoppingCartName}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+ Wait Until Element Is Visible ${shopping_car_icon_header_menu_item}[${env}]
+ Mouse Over ${shopping_car_icon_header_menu_item}[${env}]
+ Wait Until Element Is Visible ${shopping_cart_sub_navigation_widget}
+ IF '${env}' in ['ui_suite']
+ Click xpath=//header//cart-counter//a[contains(@href,'/cart')]/ancestor::li//ul[contains(@class,'menu')][contains(@class,'wide')]//*[contains(@data-qa,'mini-cart-detail')]//a[contains(.,'${shoppingCartName}')] | //header//cart-counter//a[contains(@href,'/cart')]/ancestor::li//ul[contains(@class,'menu')][contains(@class,'wide')]//*[contains(@data-qa,'mini-cart-detail')]//button[contains(.,'${shoppingCartName}')]
+ ELSE
+ Click xpath=//*[contains(@class,'icon--cart')]/ancestor::li//div[contains(@class,'js-user-navigation__sub-nav-cart')]//div[@class='mini-cart-detail']//*[contains(@class,'mini-cart-detail__title')]/*[text()='${shoppingCartName}']
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: go to shopping cart page through the header
+ Yves: remove flash messages
+ Wait Until Element Is Visible ${shopping_car_icon_header_menu_item}[${env}]
+ Click ${shopping_car_icon_header_menu_item}[${env}]
+ Wait Until Element Is Visible ${shopping_cart_main_content_locator}[${env}]
+ Reload
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${shopping_cart_main_content_locator}[${env}]
+
+Yves: go to shopping cart page
+ Yves: go to URL: /cart
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ Wait Until Element Is Not Visible ${shopping_cart_ajax_loader}
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: shopping cart contains the following products:
+ [Documentation] For item listing you can use sku or name of the product
+ [Arguments] @{items_list}
+ ${items_list_count}= get length ${items_list}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ FOR ${index} IN RANGE 0 ${items_list_count}
+ ${item_to_check}= Get From List ${items_list} ${index}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element locator=xpath=(//main//cart-items-list//product-item[contains(@data-qa,'component product-cart-item')]//*[@data-qa='cart-item-sku'][contains(text(),'${item_to_check}')])[1] timeout=${browser_timeout}
+ ELSE
+ Page Should Contain Element locator=xpath=(//main[contains(@class,'cart')]//article[(contains(@data-qa,'product-cart-item') or contains(@data-qa,'product-card-item'))]//*[contains(.,'${item_to_check}')]/ancestor::article)[1] timeout=${browser_timeout}
+ END
+ END
+
+Yves: preview shopping cart contains the following products:
+ [Documentation] For item listing you can use sku or name of the product
+ [Arguments] @{items_list}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${items_list_count}= get length ${items_list}
+ FOR ${index} IN RANGE 0 ${items_list_count}
+ ${item_to_check}= Get From List ${items_list} ${index}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=(//main//product-item[contains(@data-qa,'component product-cart-item')]//*[@data-qa='cart-item-sku'][contains(text(),'${item_to_check}')])[1]
+ ELSE
+ Page Should Contain Element xpath=(//main[contains(@class,'cart')]//article[(contains(@data-qa,'product-cart-item') or contains(@data-qa,'product-card-item'))]//*[contains(.,'${item_to_check}')]/ancestor::article)[1]
+ END
+ END
+
+Yves: click on the '${buttonName}' button in the shopping cart
+ Yves: remove flash messages
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${buttonName}' == 'Checkout'
+ Click ${shopping_cart_checkout_button}
+ Wait Until Page Does Not Contain Element ${shopping_cart_checkout_button}
+ ELSE IF '${buttonName}' == 'Request a Quote'
+ Click ${shopping_cart_request_quote_button}
+ Wait Until Page Does Not Contain Element ${shopping_cart_request_quote_button}
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: shopping cart contains product with unit price:
+ [Arguments] ${sku} ${productName} ${productPrice}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ TRY
+ Page Should Contain Element xpath=//div[contains(@class,'product-card-item__col--description')]//div[contains(.,'SKU: ${sku}')]/ancestor::article//*[contains(@class,'product-card-item__col--description')]/div[1]//*[contains(@class,'money-price__amount')][contains(.,'${productPrice}')] timeout=300ms
+ EXCEPT
+ Page Should Contain Element xpath=//div[contains(@class,'product-cart-item__col--description')]//div[contains(.,'SKU: ${sku}')]/ancestor::article//*[contains(@class,'product-cart-item__col--description')]/div[1]//*[contains(@class,'money-price__amount')][contains(.,'${productPrice}')] timeout=300ms
+ END
+ ELSE IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//main//cart-items-list//product-item[contains(@data-qa,'component product-cart-item')]//*[@data-qa='cart-item-sku'][contains(text(),'${sku}')]/ancestor::product-item//*[contains(@data-qa,'cart-item-summary')]//span[contains(.,'${productPrice}')] timeout=300ms
+ ELSE
+ Page Should Contain Element xpath=//main[@class='page-layout-cart']//article[contains(@data-qa,'component product-card-item')]//a[contains(text(),'${productName}')]/following-sibling::span/span[contains(@class,'money-price__amount') and contains(.,'${productPrice}')] timeout=300ms
+ END
+
+Yves: shopping cart contains/doesn't contain the following elements:
+ [Arguments] ${condition} @{shopping_cart_elements_list} ${element1}=${EMPTY} ${element2}=${EMPTY} ${element3}=${EMPTY} ${element4}=${EMPTY} ${element5}=${EMPTY} ${element6}=${EMPTY} ${element7}=${EMPTY} ${element8}=${EMPTY} ${element9}=${EMPTY} ${element10}=${EMPTY} ${element11}=${EMPTY} ${element12}=${EMPTY} ${element13}=${EMPTY} ${element14}=${EMPTY} ${element15}=${EMPTY}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${condition}= Convert To Lower Case ${condition}
+ ${shopping_cart_elements_list_count}= get length ${shopping_cart_elements_list}
+ FOR ${index} IN RANGE 0 ${shopping_cart_elements_list_count}
+ ${shopping_cart_element_to_check}= Get From List ${shopping_cart_elements_list} ${index}
+ IF '${condition}' == 'true'
+ Run Keywords
+ Log ${shopping_cart_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Contain Element ${shopping_cart_element_to_check} message=${shopping_cart_element_to_check} is not displayed
+ END
+ IF '${condition}' == 'false'
+ Run Keywords
+ Log ${shopping_cart_element_to_check} #Left as an example of multiple actions in Condition
+ Page Should Not Contain Element ${shopping_cart_element_to_check} message=${shopping_cart_element_to_check} should not be displayed
+ END
+ END
+
+Yves: shopping cart with name xxx has the following status:
+ [Arguments] ${cartName} ${status}
+ Page Should Contain Element //*[@data-qa='component quote-table']//table//td[@data-content='Name'][contains(.,'${cartName}')]/../td//*[contains(@data-qa,'component quote-status')][contains(.,'${status}')]
+
+Yves: delete product from the shopping cart with sku:
+ [Arguments] ${sku}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click xpath=//form[contains(@name,'removeFromCartForm_${sku}')]//button
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+
+Yves: delete product from the shopping cart with name:
+ [Arguments] ${productName}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Click //main[@class='page-layout-cart']//article[contains(@data-qa,'component product-card-item')]//a[contains(text(),'${productName}')]/ancestor::article//form[contains(@name,'removeFromCartForm')]//button | //div[contains(@class,'box cart-items-list')]//a[contains(text(),'${productName}')]//ancestor::*[@data-qa='component product-cart-item']//button[contains(text(),'remove')]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ Wait For Load State networkidle
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+
+Yves: shopping cart doesn't contain the following products:
+ [Arguments] @{sku_list} ${sku1}=${EMPTY} ${sku2}=${EMPTY} ${sku3}=${EMPTY} ${sku4}=${EMPTY} ${sku5}=${EMPTY} ${sku6}=${EMPTY} ${sku7}=${EMPTY} ${sku8}=${EMPTY} ${sku9}=${EMPTY} ${sku10}=${EMPTY} ${sku11}=${EMPTY} ${sku12}=${EMPTY} ${sku13}=${EMPTY} ${sku14}=${EMPTY} ${sku15}=${EMPTY}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ Page Should Not Contain Element xpath=//form[contains(@name,'removeFromCartForm_${sku_to_check}')]
+ END
+
+Yves: get link for external cart sharing
+ Reload
+ IF '${env}' in ['ui_suite']
+ Click xpath=//input[@name='cart-share'][contains(@target-class-name,'external')]/ancestor::label
+ ELSE
+ Click xpath=//div[@data-qa='component cart-sidebar']//*[contains(@data-qa,'url-mask-generator')]//ancestor::*[contains(@data-qa,'cart-sidebar-item')]//*[@data-toggle-target]
+ Click xpath=//input[@name='cart-share'][contains(@target-class-name,'external')]/ancestor::label
+ END
+ Wait Until Element Is Visible xpath=//input[@id='PREVIEW']
+ ${externalURL}= Get Element Attribute xpath=//input[@id='PREVIEW'] value
+ ${externalURL}= Replace String Using Regexp ${externalURL} ${EMPTY}.*.com/ ${EMPTY}
+ Set Suite Variable ${externalURL}
+
+Yves: Expand shopping cart accordion:
+ [Arguments] ${accordionTitle}
+ ${accordionState}= Get Element Attribute xpath=//div[@data-qa='component cart-sidebar']//*[contains(@class,'cart-sidebar-item__title')][contains(.,'${accordionTitle}')] class
+ ${accordionState}= Replace String ${accordionState} ${SPACE} ${EMPTY}
+ ${accordionState}= Replace String ${accordionState} _ ${SPACE}
+ ${accordionState}= Replace String ${accordionState} - ${SPACE}
+ ${accordionState}= Replace String ${accordionState} \r ${EMPTY}
+ ${accordionState}= Replace String ${accordionState} \n ${EMPTY}
+ IF 'active' not in '${accordionState}'
+ Run Keywords
+ Click With Options xpath=//div[@data-qa='component cart-sidebar']//*[contains(@class,'cart-sidebar-item__title')][contains(.,'${accordionTitle}')] delay=1s force=True
+ Wait Until Element Is Visible xpath=//div[@data-qa='component cart-sidebar']//*[contains(@class,'cart-sidebar-item__title')][contains(.,'${accordionTitle}')]/../div[contains(@class,'cart-sidebar-item__content')]
+ END
+
+Yves: Shopping Cart title should be equal:
+ [Arguments] ${expectedCartTitle}
+ ${actualCartTitle}= Get Text ${shopping_cart_cart_title}[${env}]
+ Should Be Equal ${actualCartTitle} ${expectedCartTitle}
+
+Yves: change quantity of the configurable bundle in the shopping cart on:
+ [Documentation] In case of multiple matches, changes quantity for the first product in the shopping cart
+ [Arguments] ${confBundleTitle} ${quantity}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2b','ui_mp_b2b','ui_suite']
+ Type Text xpath=//main//article[contains(@data-qa,'configured-bundle')][1]//a[text()='${confBundleTitle}']/ancestor::article//input[contains(@class, 'formatted-number-input__input')] ${quantity}
+ ELSE
+ Type Text xpath=//article[contains(@data-qa,'configured-bundle-secondary')][1]//ancestor::*[contains(@data-qa, 'component formatted-number-input')]//input[contains(@class,'formatted-number-input')][contains(@data-min-quantity,'1')] ${quantity}
+ END
+ IF '${env}' in ['ui_suite']
+ Click //main//article[contains(@data-qa,'configured-bundle')][1]//a[text()='${confBundleTitle}']/ancestor::article//input[contains(@class, 'formatted-number-input__input')]/ancestor::article//button[@data-qa='quantity-input-submit']
+ END
+ Click With Options xpath=//main//article[contains(@data-qa,'configured-bundle')][1]//a[text()='${confBundleTitle}']/ancestor::article delay=1s
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+
+Yves: delete all shopping carts
+ Yves: create new 'Shopping Cart' with name: Y
+ #create new empty cart that will be the last one in the list
+ ${currentURL}= Get Location
+ IF '/multi-cart' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}multi-cart
+ ELSE
+ Go To ${yves_url}multi-cart
+ END
+ END
+ ${shoppingCartsCount}= Get Element Count xpath=//*[@data-qa='component quote-table']//table/tbody/tr//a[contains(.,'Delete')]
+ FOR ${index} IN RANGE 0 ${shoppingCartsCount}-1
+ Delete first available shopping cart
+ Wait Until Element Is Visible ${delete_shopping_cart_button}
+ Click ${delete_shopping_cart_button}
+ END
+
+Yves: delete 'Shopping Cart' with name:
+ [Arguments] ${shoppingCartName}
+ ${currentURL}= Get Location
+ IF '/multi-cart' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}multi-cart
+ ELSE
+ Go To ${yves_url}multi-cart
+ END
+ END
+ Delete shopping cart with name: ${shoppingCartName}
+ Wait Until Element Is Visible ${delete_shopping_cart_button}
+ Click ${delete_shopping_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: delete from b2c cart products with name:
+ [Arguments] @{productNameList}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ FOR ${product} IN @{productNameList}
+ Click xpath=//div[@class='page-layout-cart__items-wrap']//a[contains(text(),'${product}')]/ancestor::div/following-sibling::div//form[contains(@name,'removeFromCart')]//button[text()='Remove']
+ Yves: flash message should be shown: success Products were removed successfully
+ Yves: remove flash messages
+ IF '${env}' in ['ui_b2b','ui_mp_b2b']
+ Page Should Not Contain Element xpath=//div[contains(@class,'product-card-item__col--description')]//div[contains(.,'${product}')]
+ ELSE
+ Page Should Not Contain Element xpath=//main[@class='page-layout-cart']//article[contains(@data-qa,'component product-card-item')]//a[contains(text(),'${product}')]
+ END
+ END
+
+Yves: apply discount voucher to cart:
+ [Arguments] ${voucherCode}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${expanded}= Set Variable ${EMPTY}
+ Disable Automatic Screenshots on Failure
+ ${expanded}= IF '${env}' in ['ui_b2c','ui_mp_b2c'] Run Keyword And Return Status Get Element States ${shopping_cart_voucher_code_field} == hidden return_names=False
+ Restore Automatic Screenshots on Failure
+ IF '${env}' in ['ui_b2c','ui_mp_b2c'] and '${expanded}'=='False' Click ${shopping_cart_voucher_code_section_toggler}
+ Type Text ${shopping_cart_voucher_code_field} ${voucherCode}
+ Click ${shopping_cart_voucher_code_redeem_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: remove flash messages
+
+Yves: discount is applied:
+#TODO: make from this method smth real, because Sum is not used
+ [Arguments] ${discountType} ${discountName} ${expectedDiscountSum}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_b2c','ui_mp_b2c'] and '${discountType}'=='voucher'
+ Element should be visible locator=xpath=//span[contains(text(),'${expectedDiscountSum}')]/preceding-sibling::span[contains(text(),'${discountName}')]/ancestor::*[contains(@data-qa,'cart-discount-summary')]/*[contains(.,'Vouchers')] timeout=${browser_timeout}
+ ELSE IF '${env}' in ['ui_b2c','ui_mp_b2c'] and '${discountType}'=='cart rule'
+ Element should be visible locator=xpath=//span[contains(text(),'${expectedDiscountSum}')]/preceding-sibling::span[contains(text(),'${discountName}')]/ancestor::*[contains(@data-qa,'cart-discount-summary')]/*[contains(.,'Discounts')] timeout=${browser_timeout}
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b'] and '${discountType}'=='voucher'
+ Element should be visible locator=xpath=//span[contains(text(),'${expectedDiscountSum}')]/preceding-sibling::span[contains(text(),'${discountName}')]/ancestor::*[contains(@data-qa,'cart-code-summary')]/*[contains(.,'Vouchers')] timeout=${browser_timeout}
+ ELSE IF '${env}' in ['ui_b2b','ui_mp_b2b'] and '${discountType}'=='cart rule'
+ Element should be visible locator=xpath=//span[contains(text(),'${expectedDiscountSum}')]/preceding-sibling::span[contains(text(),'${discountName}')]/ancestor::*[contains(@data-qa,'cart-code-summary')]/*[contains(.,'Discounts')] timeout=${browser_timeout}
+ END
+
+Yves: promotional product offer is/not shown in cart:
+ [Arguments] ${isShown}
+ ${isShown}= Convert To Lower Case ${isShown}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${isShown}'=='true'
+ Try reloading page until element is/not appear: ${shopping_cart_promotional_product_section} true 5
+ Element Should Be Visible ${shopping_cart_promotional_product_section} message=Promotional products are not displayed but should be timeout=${browser_timeout}
+ ELSE IF '${isShown}'=='false'
+ Try reloading page until element is/not appear: ${shopping_cart_promotional_product_section} false 5
+ Element Should Not Be Visible ${shopping_cart_promotional_product_section} message=Promotional products are displayed but should not timeout=${browser_timeout}
+ END
+
+Yves: change quantity of promotional product and add to cart:
+ [Documentation] set ${action} to + or - to change quantity. ${clickCount} indicates how many times to click
+ [Arguments] ${action} ${clicksCount}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ FOR ${index} IN RANGE 0 ${clicksCount}
+ IF '${action}' == '+'
+ Click ${shopping_cart_promotional_product_increase_quantity_button}[${env}]
+ ELSE IF '${action}' == '-'
+ Click ${shopping_cart_promotional_product_decrease_quantity_button}[${env}]
+ END
+ END
+ Click ${shopping_cart_promotional_product_add_to_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: flash message should be shown: success Items added successfully
+ Yves: remove flash messages
+
+Yves: add promotional product to the cart
+ [Documentation]
+ Click ${shopping_cart_promotional_product_add_to_cart_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: flash message should be shown: success Items added successfully
+ Yves: remove flash messages
+
+Yves: assert merchant of product in b2c cart:
+ [Documentation] Method for MP which asserts value in 'Sold by' label of item in cart or list. Requires concrete SKU
+ [Arguments] ${product_name} ${merchant_name_expected}
+ Page Should Contain Element xpath=//main[contains(@class,'cart')]//article[contains(@data-qa,'component product-card-item')]//*[contains(.,'${product_name}')]/ancestor::article//*[@data-qa='component sold-by-merchant']/a[text()='${merchant_name_expected}']
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/shopping_lists_steps.robot b/atest/testdata/performance/resources/steps/shopping_lists_steps.robot
new file mode 100644
index 0000000..f46e527
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/shopping_lists_steps.robot
@@ -0,0 +1,117 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../pages/yves/yves_shopping_lists_page.robot
+Resource ../common/common_yves.robot
+Resource ../pages/yves/yves_delete_shopping_list_page.robot
+Resource customer_account_steps.robot
+Resource order_history_steps.robot
+
+*** Keywords ***
+Yves: 'Shopping List' widget contains:
+ [Arguments] ${shoppingListName} ${accessLevel}
+ Wait Until Element Is Visible ${shopping_list_icon_header_menu_item}[${env}]
+ Mouse Over ${shopping_list_icon_header_menu_item}[${env}]
+ Wait Until Element Is Visible ${shopping_list_sub_navigation_widget}[${env}]
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//header//li[contains(@class,'item')]//a[contains(@href,'shopping-list')]/ancestor::li//*[contains(@class,'list')]//li//a[contains(.,'${shoppingListName}')]/ancestor::li/div[contains(@class,'list-item')]//*[contains(@class,'access')][contains(.,'${accessLevel}')]
+ ELSE
+ Page Should Contain Element xpath=//header//li[contains(@class,'item')]/span[contains(@class,'item-inner')]//a[contains(@href,'shopping-list')]/ancestor::span/*[contains(@class,'list')]//li//a[contains(.,'${shoppingListName}')]/ancestor::li/div[contains(@class,'list-item')]//*[contains(@class,'access')][contains(.,'${accessLevel}')]
+ END
+
+Yves: go to 'Shopping Lists' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/shopping-list
+
+Yves: create new 'Shopping List' with name:
+ [Arguments] ${shoppingListName}
+ ${currentURL}= Get Location
+ IF '/shopping-list' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}shopping-list
+ ELSE
+ Go To ${yves_url}shopping-list
+ END
+ END
+ Type Text ${shopping_list_name_input_field} ${shoppingListName}
+ Click ${create_shopping_list_button}
+
+Yves: the following shopping list is shown:
+ [Arguments] ${shoppingListName} ${shoppingListOwner} ${shoppingListAccess}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=//*[contains(@data-qa,"shopping-list-overview")]//table//td//span[contains(@data-qa,'shopping-list-permission')][contains(.,'${shoppingListAccess}')]/ancestor::tr/td[contains(.,'${shoppingListOwner}')]/ancestor::tr/td[contains(@class,'name')][contains(.,'${shoppingListName}')]
+ ELSE
+ Page Should Contain Element xpath=//*[@data-qa="component shopping-list-overview-table"]//table//td[@data-content='Access'][contains(.,'${shoppingListAccess}')]/../td[@data-content='Owner'][contains(.,'${shoppingListOwner}')]/../td[@data-content='Name'][contains(.,'${shoppingListName}')]
+ END
+
+Yves: share shopping list with user:
+ [Arguments] ${shoppingListName} ${customer} ${accessLevel}
+ Share shopping list with name: ${shoppingListName}
+ Select access level to share shopping list with: ${customer} ${accessLevel}
+ Click ${share_shopping_list_confirm_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Yves: 'Shopping Lists' page is displayed
+ Yves: flash message 'should' be shown
+
+Yves: shopping list contains the following products:
+ [Arguments] @{sku_list} ${sku1}=${EMPTY} ${sku2}=${EMPTY} ${sku3}=${EMPTY} ${sku4}=${EMPTY} ${sku5}=${EMPTY} ${sku6}=${EMPTY} ${sku7}=${EMPTY} ${sku8}=${EMPTY} ${sku9}=${EMPTY} ${sku10}=${EMPTY} ${sku11}=${EMPTY} ${sku12}=${EMPTY} ${sku13}=${EMPTY} ${sku14}=${EMPTY} ${sku15}=${EMPTY}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ ${sku_list_count}= get length ${sku_list}
+ FOR ${index} IN RANGE 0 ${sku_list_count}
+ ${sku_to_check}= Get From List ${sku_list} ${index}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=(//table[contains(@data-qa,'shopping-list')]/tbody/tr//*[@itemprop='sku'][contains(.,'${sku_to_check}')])[1]
+ ELSE
+ Page Should Contain Element xpath=(//*[@data-qa='component shopping-list-table']//div[contains(@class,'product-card-item__col--description')]//div[contains(.,'SKU: ${sku_to_check}')]/ancestor::article)[1]
+ END
+ END
+
+Yves: delete 'Shopping List' with name:
+ [Arguments] ${shoppingListName}
+ ${currentURL}= Get Location
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}shopping-list
+ ELSE
+ Go To ${yves_url}shopping-list
+ END
+ Delete shopping list with name: ${shoppingListName}
+ Wait Until Element Is Visible ${delete_shopping_list_button}
+ Click ${delete_shopping_list_button}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Yves: view shopping list with name:
+ [Arguments] ${shoppingListName}
+ ${currentURL}= Get Location
+ IF '/shopping-list' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}shopping-list
+ ELSE
+ Go To ${yves_url}shopping-list
+ END
+ END
+ View shopping list with name: ${shoppingListName}
+
+Yves: add all available products from list to cart
+ Wait Until Element Is Visible ${shopping_list_main_content_locator}
+ Click ${add_all_available_products_to_cart_locator}
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/users_steps.robot b/atest/testdata/performance/resources/steps/users_steps.robot
new file mode 100644
index 0000000..c95fcf8
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/users_steps.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Resource ../pages/zed/zed_delete_user_confirmation_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: delete Zed user with the following email:
+ [Arguments] ${zed_email}
+ ${currentURL}= Get Location
+ IF '/user' not in '${currentURL}' Zed: go to URL: /user
+ Zed: click Action Button in a table for row that contains: ${zed_email} Delete
+ Wait Until Page Contains Element ${zed_confirm_delete_user_button}
+ Click ${zed_confirm_delete_user_button}
diff --git a/atest/testdata/performance/resources/steps/warehouse_user_assignment_steps.robot b/atest/testdata/performance/resources/steps/warehouse_user_assignment_steps.robot
new file mode 100644
index 0000000..a0ecd8b
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/warehouse_user_assignment_steps.robot
@@ -0,0 +1,77 @@
+*** Settings ***
+Library DatabaseLibrary
+Library BuiltIn
+Library ../../resources/libraries/common.py
+Resource ../common/common_api.robot
+
+*** Keywords ***
+
+Create_warehouse_user_assignment:
+ [Documentation] This keyword creates new warehouse user assignment in the DB table `spy_warehouse_user_assignment`.
+ ... *Example:*
+ ...
+ ... ``Create_warehouse_user_assignment: ${warehouse_uuid} ${user_uuid} false``
+ ...
+ [Arguments] ${warehouse_uuid} ${fk_warehouse} ${user_uuid} ${isActive}
+ ${idWarehouseUserAssignment}= Get next id from table spy_warehouse_user_assignment id_warehouse_user_assignment
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String insert ignore into spy_warehouse_user_assignment (uuid, fk_warehouse, user_uuid, is_active) value ('${warehouse_uuid}',${fk_warehouse}, '${user_uuid}', ${isActive});
+ ELSE
+ Execute Sql String INSERT INTO spy_warehouse_user_assignment (id_warehouse_user_assignment, uuid, fk_warehouse, user_uuid, is_active) VALUES (${idWarehouseUserAssignment},'${warehouse_uuid}',${fk_warehouse}, '${user_uuid}', ${isActive});
+ END
+ Disconnect From Database
+
+Get_warehouse_user_assignment_id:
+ [Documentation] This keyword retrieve warehouse user assignment ${id_warehouse_user_assignment} in the DB table `spy_warehouse_user_assignment` by uuid and user_uuid.
+ ... *Example:*
+ ...
+ ... ``Get_warehouse_user_assignment_id: ${warehouse_uuid} ${user_uuid}`
+ ...
+ [Arguments] ${warehouse_uuid} ${user_uuid}
+ Connect to Spryker DB
+ ${id_warehouse_user_assignment}= Query SELECT id_warehouse_user_assignment FROM spy_warehouse_user_assignment WHERE uuid = '${warehouse_uuid}' AND user_uuid='${user_uuid}';
+ Disconnect From Database
+ Set Test Variable ${id_warehouse_user_assignment} ${id_warehouse_user_assignment[0][0]}
+ RETURN ${id_warehouse_user_assignment}
+
+Remove_warehouse_user_assignment:
+ [Documentation] This keyword deletes the entry from the DB table `spy_warehouse_user_assignment`.
+ ... *Example:*
+ ...
+ ... ``Remove_warehouse_user_assignment: ${warehouse_uuid} ${user_uuid}``
+ ...
+ [Arguments] ${warehouse_uuid} ${user_uuid}
+ ${id_warehouse_user_assignment}= Get_warehouse_user_assignment_id: ${warehouse_uuid} ${user_uuid}
+ Connect to Spryker DB
+ Execute Sql String DELETE FROM spy_warehouse_user_assignment WHERE id_warehouse_user_assignment = ${id_warehouse_user_assignment};
+ Disconnect From Database
+
+Remove all warehouse user assignments by user uuid:
+ [Documentation] This keyword deletes all entries from the DB table `spy_warehouse_user_assignment` matching provided user_uuid.
+ ... *Example:*
+ ...
+ ... ``Remove all warehouse user assignments by user uuid: ${user_uuid}``
+ ...
+ [Arguments] ${user_uuid}
+ Connect to Spryker DB
+ ${assignments}= Query SELECT id_warehouse_user_assignment FROM spy_warehouse_user_assignment WHERE user_uuid='${user_uuid}'
+ FOR ${row} IN @{assignments}
+ ${assignment_id}= Set Variable ${row}[0]
+ Execute Sql String DELETE FROM spy_warehouse_user_assignment WHERE id_warehouse_user_assignment = ${assignment_id}
+ END
+
+Make user a warehouse user/ not a warehouse user:
+ [Documentation] This keyword update user with warehouse assignment in the DB table `spy_user`.
+ ... *Example:*
+ ...
+ ... ``Make user a warehouse user/ not a warehouse user: ${user_uuid} 0``
+ ...
+ [Arguments] ${user_uuid} ${isActive}
+ Connect to Spryker DB
+ IF '${db_engine}' == 'pymysql'
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = '${isActive}' WHERE uuid = '${user_uuid}';
+ ELSE
+ Execute Sql String UPDATE spy_user SET is_warehouse_user = '${isActive}' WHERE uuid = '${user_uuid}';
+ END
+ Disconnect From Database
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/wishlist_steps.robot b/atest/testdata/performance/resources/steps/wishlist_steps.robot
new file mode 100644
index 0000000..3d65632
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/wishlist_steps.robot
@@ -0,0 +1,139 @@
+*** Settings ***
+Resource ../common/common.robot
+Resource ../../resources/common/common_yves.robot
+Resource ../pages/yves/yves_wishlist_page.robot
+
+*** Keywords ***
+Yves: go to 'Wishlist' page
+ ${lang}= Yves: get current lang
+ Yves: go to URL: ${lang}/wishlist
+
+Yves: go to wishlist with name:
+ [Arguments] ${wishlistName}
+ Yves: go to 'Wishlist' page
+ Click xpath=//*[contains(@data-qa,'wishlist-overview')]//table//a[contains(text(),'${wishlistName}')]
+ Element Should Be Visible xpath=//main//*[contains(@class,'title')][contains(text(),'${wishlistName}')]
+
+Yves: product with sku is marked as discontinued in wishlist:
+ [Arguments] ${productSku}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ FOR ${index} IN RANGE 0 21
+ Disable Automatic Screenshots on Failure
+ ${discontinue_applied}= Run Keyword And Return Status Page Should Contain Element xpath=//li[contains(text(),'${productSku}')]/ancestor::td/following-sibling::td/span[contains(text(),'Discontinued')]
+ Restore Automatic Screenshots on Failure
+ IF '${discontinue_applied}'=='False'
+ Run Keywords
+ Sleep 1s
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger p&s
+ END
+ END
+ Element Should Be Visible xpath=//li[contains(text(),'${productSku}')]/ancestor::td/following-sibling::td/span[contains(text(),'Discontinued')]
+
+Yves: product with sku is marked as alternative in wishlist:
+ [Arguments] ${productSku}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ FOR ${index} IN RANGE 0 21
+ Disable Automatic Screenshots on Failure
+ IF '${env}' in ['ui_suite']
+ ${alternative_applied}= Run Keyword And Return Status Page Should Contain Element xpath=//*[contains(@data-qa,'wishlist-table')]//td//a/../*[contains(.,'${productSku}')]/following-sibling::*[contains(text(),'Alternative for')]
+ ELSE
+ ${alternative_applied}= Run Keyword And Return Status Page Should Contain Element xpath=//li[contains(text(),'${productSku}')]/ancestor::tr/preceding-sibling::tr//*[contains(text(),'Alternative for')]
+ END
+ Restore Automatic Screenshots on Failure
+ IF '${alternative_applied}'=='False'
+ Sleep 1s
+ Reload
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log page is not fully loaded
+ END
+ ELSE
+ Exit For Loop
+ END
+ IF ${index} == 2 or ${index} == 5
+ Trigger p&s
+ END
+ END
+ IF '${env}' in ['ui_suite']
+ Element Should Be Visible xpath=//*[contains(@data-qa,'wishlist-table')]//td//a/../*[contains(.,'${productSku}')]/following-sibling::*[contains(text(),'Alternative for')]
+ ELSE
+ Element Should Be Visible xpath=//li[contains(text(),'${productSku}')]/ancestor::tr/preceding-sibling::tr//*[contains(text(),'Alternative for')]
+ END
+
+Yves: create wishlist with name:
+ [Arguments] ${wishlistName}
+ ${currentURL}= Get Location
+ IF '/wishlist/detail' in '${currentURL}' or '/wishlist' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}wishlist
+ ELSE
+ Go To ${yves_url}wishlist
+ END
+ END
+ Type Text ${wishlist_name_input_field} ${wishlistName}
+ Click ${wishlist_add_new_button}
+ Yves: flash message should be shown: success Wishlist created successfully.
+ Yves: remove flash messages
+
+Yves: wishlist contains product with sku:
+ [Arguments] ${productSku}
+ Element Should Be Visible xpath=//*[contains(@data-qa,'wishlist')][contains(@data-qa,'table')]//li[contains(text(),'${productSku}')] message=Product with ${productSku} sku is not found in wishlist
+
+Yves: delete all wishlists
+ Yves: go to 'Wishlist' page
+ ${wishlists_list_count}= Get Element Count ${wishlist_delete_button}
+ FOR ${index} IN RANGE 0 ${wishlists_list_count}
+ Click ${wishlist_delete_button}\[1\]
+ Yves: flash message should be shown: success Wishlist deleted successfully
+ Yves: remove flash messages
+ END
+
+Yves: assert merchant of product in wishlist:
+ [Documentation] Method for MP which asserts value in 'Sold by' label of item in wishlist. Requires concrete SKU
+ [Arguments] ${sku} ${merchant_name_expected}
+ IF '${env}' in ['ui_suite']
+ Page Should Contain Element xpath=(//*[contains(@data-qa,'wishlist-table')]//td[contains(.,'${sku}')]//a[contains(@href,'merchant')][contains(text(),'${merchant_name_expected}')])[1]
+ ELSE
+ Page Should Contain Element xpath=//ul[@class='menu menu--inline menu--middle']//li[contains(text(),'${sku}')]/../li/p[@data-qa='component sold-by-merchant']//a[text()='${merchant_name_expected}']
+ END
+
+Yves: add all available products from wishlist to cart
+ Wait Until Element Is Visible ${wishlist_add_all_to_cart_button}
+ Click ${wishlist_add_all_to_cart_button}
+
+Yves: create new 'Wishlist' with name:
+ [Arguments] ${wishlistName}
+ ${currentURL}= Get Location
+ IF '/wishlist/detail' in '${currentURL}' or '/wishlist' not in '${currentURL}'
+ IF '.at.' in '${currentURL}'
+ Go To ${yves_at_url}wishlist
+ ELSE
+ Go To ${yves_url}wishlist
+ END
+ END
+ Type Text ${wishlist_name_input_field} ${wishlistName}
+ Click ${wishlist_add_new_button}
+ Yves: remove flash messages
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_availability_steps.robot b/atest/testdata/performance/resources/steps/zed_availability_steps.robot
new file mode 100644
index 0000000..1afacc9
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_availability_steps.robot
@@ -0,0 +1,87 @@
+*** Settings ***
+Resource ../pages/zed/zed_availability_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: check if product is/not in stock:
+ [Arguments] ${sku} ${isInStock}
+ ${currentURL}= Get Location
+ IF '/availability-gui' not in '${currentURL}' Zed: go to URL: /availability-gui
+ IF '/availability-gui/index/edit' in '${currentURL}' Zed: go to URL: /availability-gui
+ ${isInStock}= Convert To Lower Case ${isInStock}
+ ${currentURL}= Get Location
+ IF '/availability-gui' not in '${currentURL}' Zed: go to URL: /availability-gui
+ IF '/availability-gui/index' in '${currentURL}' Zed: go to URL: /availability-gui
+ Zed: perform search by: ${sku}
+ IF '${isInStock}'=='true'
+ Element Text Should Be ${zed_availability_product_availability_label} Available Message='Expected product availability is not found'
+ ELSE
+ Element Text Should Be ${zed_availability_product_availability_label} Not available Message='Expected product availability is not found'
+ END
+
+Zed: change product stock:
+ [Arguments] ${skuORnameAbstract} ${skuConcrete} ${isNeverOutOfStock} ${quantityWarehouse1} ${quantityWarehouse2}=0
+ ${isNeverOutOfStock}= Convert To Lower Case ${isNeverOutOfStock}
+ ${currentURL}= Get Location
+ IF '/availability-gui' not in '${currentURL}' Zed: go to URL: /availability-gui
+ IF '/availability-gui/index' in '${currentURL}' Zed: go to URL: /availability-gui
+ Zed: perform search by: ${skuORnameAbstract}
+ TRY
+ Set Browser Timeout 5s
+ Click xpath=//a[contains(text(),'${skuORnameAbstract}')]/ancestor::tr//following-sibling::td//*[contains(.,'View')]
+ EXCEPT
+ Set Browser Timeout 5s
+ Click xpath=//td[contains(text(), '${skuORnameAbstract}')]/ancestor::tr//following-sibling::td//*[contains(.,'View')]
+ END
+ Set Browser Timeout ${browser_timeout}
+ Element Should Be Visible xpath=//div[@class='ibox float-e-margins']/*[contains(.,'Variant availability')]
+ Click xpath=//*[contains(text(),'${skuConcrete}')]/ancestor::tr//following-sibling::td//*[contains(.,'Edit Stock')]
+ Element Should Be Visible xpath=//div[@class='ibox float-e-margins']/*[contains(.,'Edit Stock')]
+ Wait Until Element Is Visible ${zed_save_button}
+ ${checkBoxes}= Get Element Count ${zed_availability_never_out_of_stock_checkbox}
+ FOR ${index} IN RANGE 1 ${checkBoxes}+1
+ IF '${isNeverOutOfStock}'=='true'
+ Check checkbox \(//*[@type='checkbox' and contains(@id,'is_never_out_of_stock')]\)\[${index}\]
+ ELSE
+ Uncheck Checkbox \(//*[@type='checkbox' and contains(@id,'is_never_out_of_stock')]\)\[${index}\]
+ END
+ END
+ Type Text xpath=//input[contains(@id,'AvailabilityGui_stock_stocks_0_quantity')] ${quantityWarehouse1}
+ Type Text xpath=//input[contains(@id,'AvailabilityGui_stock_stocks_1_quantity')] ${quantityWarehouse2}
+ Click ${zed_save_button}
+ #Resave to apply changes
+ Set Browser Timeout 1s
+ TRY
+ Click ${zed_save_button}
+ EXCEPT
+ Log Form is already submitted
+ END
+ Set Browser Timeout ${browser_timeout}
+ Trigger multistore p&s
+
+Zed: check and restore product availability in Zed:
+ [Arguments] ${skuAbstract} ${expectedStatus} ${skuConcrete} ${admin_user_email}=${zed_admin_email}
+ ${expectedStatus}= Convert To Lower Case ${expectedStatus}
+ ${currentURL}= Get Location
+ ${dynamic_admin_user_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ IF ${dynamic_admin_user_exists} and '${admin_email}' == '${zed_admin_email}'
+ VAR ${admin_email} ${dynamic_admin_user}
+ ELSE IF not ${dynamic_admin_user_exists}
+ VAR ${admin_email} ${zed_admin_email}
+ END
+ IF '${zed_url}' not in '${currentURL}' or '${zed_url}security-gui/login' in '${currentURL}'
+ Zed: login on Zed with provided credentials: ${admin_email}
+ END
+ Zed: go to URL: /availability-gui
+ Zed: perform search by: ${skuAbstract}
+ Disable Automatic Screenshots on Failure
+ ${isProductAvailable}= Run Keyword And Return Status Element Text Should Be ${zed_availability_product_availability_label} Available
+ Restore Automatic Screenshots on Failure
+ IF '${expectedStatus}'=='available' and '${isProductAvailable}'=='False'
+ Zed: change product stock: ${skuAbstract} ${skuConcrete} true 10 0
+ ELSE
+ IF '${expectedStatus}'=='not available' and '${isProductAvailable}'=='True'
+ Zed: change product stock: ${skuAbstract} ${skuConcrete} false 0 0
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_cms_block_steps.robot b/atest/testdata/performance/resources/steps/zed_cms_block_steps.robot
new file mode 100644
index 0000000..65c8bb3
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_cms_block_steps.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Resource ../pages/zed/zed_cms_page_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+
+Zed: assigned store to cms block:
+ [Arguments] ${store} ${block_name}
+ Zed: go to URL: /cms-block-gui/list-block
+ Zed: perform search by: ${block_name}
+ Zed: click Action Button in a table for row that contains: ${block_name} Edit Block
+ Set Browser Timeout ${browser_timeout}
+ Wait Until Element Is Visible xpath=//div[@id='cms_block_storeRelation']//label[normalize-space(.)='${store}']//input[@type='checkbox']
+ Zed: Check checkbox by Label: ${store}
+ Click ${zed_cms_block_save_button}
+ Zed: message should be shown: CMS Block was updated successfully.
+ Trigger multistore p&s
diff --git a/atest/testdata/performance/resources/steps/zed_cms_page_steps.robot b/atest/testdata/performance/resources/steps/zed_cms_page_steps.robot
new file mode 100644
index 0000000..c5438df
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_cms_page_steps.robot
@@ -0,0 +1,124 @@
+*** Settings ***
+Resource ../pages/zed/zed_cms_page_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: create a cms page and publish it:
+ [Arguments] ${enName} ${enURL} ${enTitlePlaceholder} ${enContentPlaceholder}
+ ${currentURL}= Get Location
+ IF 'list-page' not in '${currentURL}' Zed: go to URL: /cms-gui/list-page
+ Click ${zed_new_cms_page_create_button}
+ ### General page information input
+ Page Should Contain Element xpath=//body//*[contains(text(),'Create CMS Page')] message=Page for CMS creation is not opened
+ Element Should Be Visible ${zed_cms_page_general_first_locale_name_field} message=First locale section of CMS page is not open
+ Scroll Element Into View ${zed_cms_page_general_second_locale_collapsed_section}
+ Set Browser Timeout 5s
+ TRY
+ Click ${zed_cms_page_general_second_locale_collapsed_section}
+ EXCEPT
+ Log Second locale section of CMS is already open
+ END
+ Set Browser Timeout ${browser_timeout}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Wait Until Element Is Visible ${zed_cms_page_general_second_locale_name_field} message=DE section of CMS page is not open timeout=3s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_cms_page_general_second_locale_collapsed_section}
+ Click ${zed_cms_page_general_second_locale_collapsed_section}
+ END
+ Wait Until Element Is Visible ${zed_cms_page_general_second_locale_name_field} message=Second locale section of CMS page is not open
+ Check checkbox ${zed_cms_page_general_is_searchable_checkbox}
+ Type Text ${zed_cms_page_general_first_locale_name_field} ${enName} delay=50ms
+ Type Text ${zed_cms_page_general_first_locale_url_field} ${enURL} delay=50ms
+ Type Text ${zed_cms_page_general_second_locale_name_field} ${enName} delay=50ms
+ Type Text ${zed_cms_page_general_second_locale_url_field} ${enURL} delay=50ms
+ Sleep 0.5s
+ Click ${zed_cms_page_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is already loaded
+ END
+ ### Placeholder information input
+ Disable Automatic Screenshots on Failure
+ ${page_was_created}= Run Keyword And Return Status Page Should Contain Element xpath=//body//*[contains(text(),'Edit Placeholders: ${enName}')]
+ Restore Automatic Screenshots on Failure
+ IF '${page_was_created}'=='False' Click ${zed_cms_page_save_button}
+ TRY
+ Page Should Contain Element xpath=//body//*[contains(text(),'Edit Placeholders: ${enName}')] message=CMS page was not created
+ EXCEPT
+ Click ${zed_cms_page_save_button}
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is already loaded
+ END
+ Page Should Contain Element xpath=//body//*[contains(text(),'Edit Placeholders: ${enName}')] message=CMS page was not created timeout=10s
+ END
+ Scroll Element Into View ${zed_cms_page_content_second_locale_title_collapsed_section}
+ Click ${zed_cms_page_content_second_locale_title_collapsed_section}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Wait Until Element Is Visible ${zed_cms_page_placeholder_title_deDE_field} message=DE section of CMS page is not open timeout=3s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_cms_page_content_second_locale_title_collapsed_section}
+ Click ${zed_cms_page_content_second_locale_title_collapsed_section}
+ END
+ Wait Until Element Is Visible ${zed_cms_page_placeholder_title_deDE_field} message=DE section of Title tab is not open
+ Clear Text ${zed_cms_page_placeholder_title_enUS_field}
+ Type Text ${zed_cms_page_placeholder_title_enUS_field} ${enTitlePlaceholder} delay=50ms
+ Clear Text ${zed_cms_page_placeholder_title_deDE_field}
+ Type Text ${zed_cms_page_placeholder_title_deDE_field} ${enTitlePlaceholder} delay=50ms
+ Zed: go to tab by link href that contains: content-content
+ Page Should Contain Element ${zed_cms_page_placeholder_content_enUS_field} message=EN section of Content tab is not visible
+ Scroll Element Into View ${zed_cms_page_content_second_locale_content_collapsed_section}
+ Click ${zed_cms_page_content_second_locale_content_collapsed_section}
+ Disable Automatic Screenshots on Failure
+ ${second_locale_section_expanded}= Run Keyword And Return Status Wait Until Element Is Visible ${zed_cms_page_placeholder_content_deDE_field} message=DE section of CMS page is not open timeout=3s
+ Restore Automatic Screenshots on Failure
+ IF '${second_locale_section_expanded}'=='False'
+ Scroll Element Into View ${zed_cms_page_content_second_locale_content_collapsed_section}
+ Click ${zed_cms_page_content_second_locale_content_collapsed_section}
+ END
+ Clear Text ${zed_cms_page_placeholder_content_enUS_field}
+ Type Text ${zed_cms_page_placeholder_content_enUS_field} ${enContentPlaceholder} delay=50ms
+ Clear Text ${zed_cms_page_placeholder_content_deDE_field}
+ Type Text ${zed_cms_page_placeholder_content_deDE_field} ${enContentPlaceholder} delay=50ms
+ Sleep 0.5s
+ ### Save and publish
+ Click ${zed_cms_page_save_button}
+ Zed: message should be shown: Placeholder translations successfully updated.
+ Click ${zed_cms_page_publish_button}
+ Zed: message should be shown: successfully published
+ ### Check the CMS page in Zed table
+ Zed: go to URL: /cms-gui/list-page
+ Zed: perform search by: ${enName}
+ Page Should Contain Element xpath=//td[contains(@class,'name') and contains(text(),'${enName}')]/following-sibling::td[contains(@class,'status')]//span[contains(@class,'label') and contains(text(),'Active')] message=CMS page is not found or not activated
+ Trigger multistore p&s
+
+Zed: update cms page and publish it:
+ [Arguments] @{args}
+ ${cmsPageData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /cms-gui/list-page
+ Zed: click Action Button in a table for row that contains: ${cmsPage} Edit
+ Set Browser Timeout 5s
+ TRY
+ Click xpath=(//a[contains(@href,'edit-page')])[2]
+ EXCEPT
+ Set Browser Timeout ${browser_timeout}
+ Click xpath=(//a[contains(@href,'edit-page')])[1]
+ END
+ Set Browser Timeout ${browser_timeout}
+ Wait Until Element Is Visible ${zed_cms_page_general_is_searchable_checkbox}
+ FOR ${key} ${value} IN &{cmsPageData}
+ IF '${key}'=='unselect store' and '${value}' != '${EMPTY}'
+ Zed: Uncheck Checkbox by Label: ${value}
+ END
+ END
+ Click ${zed_cms_page_save_button}
+ Click ${zed_cms_page_publish_button}
+ Zed: message should be shown: successfully published
+ Trigger multistore p&s
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_customer_steps.robot b/atest/testdata/performance/resources/steps/zed_customer_steps.robot
new file mode 100644
index 0000000..90cfc39
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_customer_steps.robot
@@ -0,0 +1,69 @@
+*** Settings ***
+Resource ../pages/zed/zed_customer_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: delete customer:
+ [Documentation] Possible argument names: email
+ [Arguments] ${email} ${admin_email}=${zed_admin_email}
+ ${currentURL}= Get Location
+ ${dynamic_admin_user_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ IF ${dynamic_admin_user_exists} and '${admin_email}' == '${zed_admin_email}'
+ VAR ${admin_email} ${dynamic_admin_user}
+ ELSE IF not ${dynamic_admin_user_exists}
+ VAR ${admin_email} ${zed_admin_email}
+ END
+ IF '${zed_url}' not in '${currentURL}' or '${zed_url}security-gui/login' in '${currentURL}'
+ Zed: login on Zed with provided credentials: ${admin_email}
+ END
+ Zed: go to URL: /customer
+ Zed: perform search by: ${email}
+ Disable Automatic Screenshots on Failure
+ ${customerExists}= Run Keyword And Return Status Element Text Should Be xpath=//tbody//td[contains(@class,' column-email') and contains(text(),'${email}')] ${email}
+ Restore Automatic Screenshots on Failure
+ IF '${customerExists}'=='True'
+ Zed: click Action Button in a table for row that contains: ${email} Edit
+ Wait Until Element Is Visible ${zed_customer_edit_page_title}
+ Click ${zed_customer_delete_button}
+ Wait Until Element Is Visible ${zed_customer_delete_confirm_button}
+ Click ${zed_customer_delete_confirm_button}
+ Zed: message should be shown: Customer successfully deleted
+ END
+
+Zed: update company customer data:
+ [Arguments] @{args}
+ ${registrationData}= Set Up Keyword Arguments @{args}
+ Zed: perform search by: ${first_name}
+ Disable Automatic Screenshots on Failure
+ ${customerExists}= Run Keyword And Return Status Zed: table should contain non-searchable value: ${first_name}
+ Restore Automatic Screenshots on Failure
+ IF '${customerExists}'=='True'
+ Zed: click Action Button in a table for row that contains: ${first_name} Edit
+ FOR ${key} ${value} IN &{registrationData}
+ IF '${key}'=='salutation' and '${value}' != '${EMPTY}'
+ Select From List By Label ${zed_edit_company_user_salutation} ${value}
+ END
+ IF '${key}'=='first_name' and '${value}' != '${EMPTY}'
+ Type Text ${zed_edit_company_user_first_name} ${value}
+ END
+ IF '${key}'=='last_name' and '${value}' != '${EMPTY}'
+ Type Text ${zed_edit_company_user_last_name} ${value}
+ END
+ IF '${key}'=='company' and '${value}' != '${EMPTY}'
+ Click ${zed_edit_company_user_company_span}
+ Wait Until Element Is Visible ${zed_edit_company_user_search_select_field}
+ Type Text ${zed_edit_company_user_search_select_field} ${value}
+ Click xpath=(//input[@type='search']/../..//ul[contains(.,'${value}')])[1]
+ END
+ IF '${key}'=='business_unit' and '${value}' != '${EMPTY}'
+ Click ${zed_edit_company_user_business_unit_span}
+ Wait Until Element Is Visible ${zed_edit_company_user_search_select_field}
+ Type Text ${zed_edit_company_user_search_select_field} ${value}
+ Click xpath=(//input[@type='search']/../..//ul[contains(.,'${value}')])[1]
+ END
+ END
+ Zed: submit the form
+ ELSE
+ Log ${email} customer doesn't exist
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_dashboard_steps.robot b/atest/testdata/performance/resources/steps/zed_dashboard_steps.robot
new file mode 100644
index 0000000..76c0d05
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_dashboard_steps.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Resource ../pages/zed/zed_customer_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_dashboard_page.robot
+
+*** Keywords ***
+Zed: check the charts and graphs present on dashboard
+ Page Should Contain Element ${dashboard_count_orders_graph}
+ Page Should Contain Element ${dashboard_orders_by_status_graph}
+ Page Should Contain Element ${dashboard_top_orders_graph}
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_discount_steps.robot b/atest/testdata/performance/resources/steps/zed_discount_steps.robot
new file mode 100644
index 0000000..b23e138
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_discount_steps.robot
@@ -0,0 +1,134 @@
+*** Settings ***
+Resource ../pages/zed/zed_discount_page.robot
+Resource ../../resources/common/common_yves.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: create a discount and activate it:
+ [Arguments] ${discountType} ${valueType} ${discountValue} ${applyToQuery}= ${voucherCode}= ${promotionalProductDiscount}=False ${promotionalProductAbstractSku}= ${promotionalProductQuantity}= ${applyWhenQuery}= ${discountName}=Test Discount ${discountDescription}='Test Description'
+ ${currentURL}= Get Location
+ IF '/discount' not in '${currentURL}' Zed: go to URL: /discount/index/list
+ ### General information
+ Zed: go to URL: /discount/index/list
+ Click ${zed_discount_add_new_discount_button}
+ Wait Until Element Is Visible ${zed_discount_create_discount_page}
+ IF '${discountType}'=='voucher'
+ Select From List By Label ${zed_discount_type_dropdown} Voucher codes
+ ELSE IF '${discountType}'=='cart rule'
+ Select From List By Label ${zed_discount_type_dropdown} Cart rule
+ END
+ Type Text ${zed_discount_name_field} ${discountName}
+ Type Text ${zed_discount_description_field} ${discountDescription}
+ Evaluate Javascript ${None} document.getElementById("discount_discountGeneral_valid_from").setAttribute("value", "01.01.2021 01:00")
+ Evaluate JavaScript ${None} document.getElementById("discount_discountGeneral_valid_to").setAttribute("value", "01.01.2030 01:00")
+ ### Discount calculation
+ Zed: go to tab by link href that contains: discount
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State ${zed_discount_query_builder_first_calculation_group} visible ${browser_timeout}
+ IF '${valueType}'=='Percentage' Run Keywords Select From List By Label ${zed_discount_calculator_type_drop_down} Percentage
+ ... AND Type Text ${zed_discount_percentage_value_field} ${discountValue}
+ ... ELSE Run keywords '${valueType}'=='Fixed amount' Select From List By Label ${zed_discount_calculator_type_drop_down} Fixed amount
+ ... AND Type Text ${zed_discount_euro_gross_field} ${discountValue}
+ IF '${promotionalProductDiscount}'=='False'
+ Run keywords
+ ... Click ${zed_discount_plain_query_apply_to__button}
+ ... AND Wait Until Element Is Visible ${zed_discount_plain_query_apply_to_field}
+ ... AND Type Text ${zed_discount_plain_query_apply_to_field} ${applyToQuery}
+ ELSE IF '${promotionalProductDiscount}'=='True'
+ Run keywords
+ ... Click ${zed_discount_promotional_product_radio}
+ ... AND Wait Until Element Is Visible ${zed_discount_promotional_product_abstract_sku_field}
+ ... AND Type Text ${zed_discount_promotional_product_abstract_sku_field} ${promotionalProductAbstractSku}
+ ... AND Type Text ${zed_discount_promotional_product_abstract_quantity_field} ${promotionalProductQuantity}
+ END
+ ### Discount condition
+ Zed: go to tab by link href that contains: conditions
+ TRY
+ Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait For Elements State ${zed_discount_query_builder_first_condition_group} visible ${browser_timeout}
+ Click ${zed_discount_plain_query_apply_when__button}
+ Wait Until Element Is Visible ${zed_discount_plain_query_apply_when_field}
+ IF '${applyWhenQuery}' != '${EMPTY}'
+ Type Text ${zed_discount_plain_query_apply_when_field} ${applyWhenQuery}
+ END
+ Click ${zed_discount_save_button}
+ Wait Until Element Is Visible ${zed_discount_activate_button}
+ Click ${zed_discount_activate_button}
+ ### Voucher codes
+ IF '${discountType}'=='voucher' Zed: generate vouchers: 1 ${voucherCode}
+ ### Check discount in Zed
+ Zed: go to URL: /discount/index/list
+ Zed: perform search by: ${discountName}
+ Element Should Be Visible xpath=//td[contains(@class,'name') and contains(text(),'${discountName}')]/ancestor::tr//span[contains(@class,'label') and contains(text(),'Active')] message=None
+
+Zed: generate vouchers:
+ [Arguments] ${quantity} ${customCode} ${addRandomLength}= ${maxNumberOfUsages}=0
+ ${currentURL}= Get Location
+ IF 'tab-content-general' not in '${currentURL}' Zed: go to tab by link href that contains: voucher
+ Type Text ${zed_discount_voucher_quantity_field} ${quantity}
+ Type Text ${zed_discount_voucher_custom_code_field} ${customCode}
+ Type Text ${zed_discount_voucher_max_usages_field} ${maxNumberOfUsages}
+ Click ${zed_discount_voucher_code_generate_button}
+
+Zed: deactivate following discounts from Overview page:
+ [Arguments] @{discountNames}
+ ${items_list_count}= get length ${discountNames}
+ Zed: go to URL: /discount/index/list
+ FOR ${name} IN @{discountNames}
+ Zed: clear search field
+ Zed: perform search by: ${name}
+ ${isDiscountActive}= Set Variable ${EMPTY}
+ Disable Automatic Screenshots on Failure
+ ${isDiscountActive}= Run Keyword And Return Status Page Should Contain Element xpath=//td[contains(text(),'${name}')]/following-sibling::td[contains(@class,'Action')]//button[contains(.,'Deactivate')] timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF '${isDiscountActive}'=='True'
+ Click xpath=//td[contains(text(),'${name}')]/following-sibling::td[contains(@class,'Action')]//button[contains(.,'Deactivate')]
+ Wait Until Element Is Visible xpath=/descendant::button[@type='submit'][contains(.,'Activate')][1]
+ END
+ END
+
+Zed: deactivate all discounts from Overview page
+ Zed: go to URL: /discount/index/list
+ Wait Until Element Is Visible xpath=/descendant::a[contains(.,'View')][1]
+ Zed: clear search field
+ Save the result of a SELECT DB query to a variable: select COUNT(id_discount) from spy_discount DiscountPagesCount
+ ${DiscountPagesCount}= Evaluate ${DiscountPagesCount} / 10
+ ${DiscountPagesCount}= Evaluate math.ceil(${DiscountPagesCount}) math
+ ${DiscountPagesCount}= Convert To Integer ${DiscountPagesCount}
+ FOR ${PagesCounter} IN RANGE 0 ${DiscountPagesCount}+1
+ ${DiscountActiveCount}= Get Element Count xpath=//button[@type='submit'][contains(.,'Deactivate')]
+ IF ${DiscountActiveCount} > 0
+ FOR ${DiscountCounter} IN RANGE 0 ${DiscountActiveCount}
+ Click xpath=/descendant::button[@type='submit'][contains(.,'Deactivate')][1]
+ Wait Until Element Is Visible xpath=/descendant::button[@type='submit'][contains(.,'Activate')][1]
+ END
+ END
+ Exit For Loop If ${PagesCounter} == ${DiscountPagesCount}
+ Click xpath=//li[contains(@class,'paginate_button')][contains(@id,'next')]
+ Sleep 2s
+ END
+
+Zed: activate following discounts from Overview page:
+ [Arguments] @{discountNames}
+ ${items_list_count}= get length ${discountNames}
+ Zed: go to URL: /discount/index/list
+ FOR ${name} IN @{discountNames}
+ Zed: clear search field
+ Zed: perform search by: ${name}
+ ${isDiscountInactive}= Set Variable ${EMPTY}
+ Disable Automatic Screenshots on Failure
+ ${isDiscountInactive}= Run Keyword And Return Status Page Should Contain Element xpath=//td[contains(text(),'${name}')]/following-sibling::td[contains(@class,'Action')]//button[contains(.,'Activate')]
+ Restore Automatic Screenshots on Failure
+ IF '${isDiscountInactive}'=='True'
+ Click xpath=//td[contains(text(),'${name}')]/following-sibling::td[contains(@class,'Action')]//button[contains(.,'Activate')]
+ Wait Until Element Is Visible xpath=/descendant::button[@type='submit'][contains(.,'Deactivate')][1]
+ END
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_marketplace_steps.robot b/atest/testdata/performance/resources/steps/zed_marketplace_steps.robot
new file mode 100644
index 0000000..faccff6
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_marketplace_steps.robot
@@ -0,0 +1,336 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_marketplace_offers_page.robot
+Resource ../pages/zed/zed_create_merchant_page.robot
+Resource zed_users_steps.robot
+
+*** Keywords ***
+Zed: select merchant in filter:
+ [Arguments] ${merchantName}
+ Select From List By Label ${zed_merchants_filter} ${merchantName}
+
+Zed: create new Merchant with the following data:
+ [Arguments] @{args}
+ ${merchantData}= Set Up Keyword Arguments @{args}
+ Zed: go to URL: /merchant-gui/list-merchant
+ Zed: click button in Header: Add Merchant
+ TRY
+ Wait Until Element Is Visible ${zed_create_merchant_name_field} timeout=10s
+ EXCEPT
+ Zed: go to URL: /merchant-gui/list-merchant
+ Zed: click button in Header: Add Merchant
+ Wait Until Element Is Visible ${zed_create_merchant_name_field}
+ END
+ VAR ${approve} False
+ FOR ${key} ${value} IN &{merchantData}
+ IF '${key}'=='merchant name' and '${value}' != '${EMPTY}'
+ Type Text ${zed_create_merchant_name_field} ${value}
+ VAR ${merchant_name} ${value}
+ END
+ IF '${key}'=='merchant reference' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_reference_field} ${value}
+ IF '${key}'=='e-mail' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_email_field} ${value}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='store 3' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='en url' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_url_en_locale_field} ${value}
+ IF '${key}'=='de url' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_url_de_locale_field} ${value}
+ IF '${key}'=='approved'
+ ${approve}= Convert To Lower Case ${value}
+ IF '${approve}' == 'true'
+ VAR ${approve} True
+ ELSE
+ VAR ${approve} False
+ END
+ END
+ IF '${key}'=='contact_first_name' and '${value}' != '${EMPTY}'
+ ${currentURL}= Get Location
+ IF '#tab-content-contact-person' not in '${currentURL}' Zed: go to tab by link href that contains: contact-person
+ Type Text ${zed_create_merchant_contact_first_name} ${value}
+ END
+ IF '${key}'=='contact_last_name' and '${value}' != '${EMPTY}'
+ ${currentURL}= Get Location
+ IF '#tab-content-contact-person' not in '${currentURL}' Zed: go to tab by link href that contains: contact-person
+ Type Text ${zed_create_merchant_contact_last_name} ${value}
+ END
+ END
+ Zed: submit the form
+ Zed: wait for button in Header to be visible: Add Merchant ${browser_timeout}
+ Zed: table should contain: ${MerchantName}
+ IF ${approve}
+ Zed: go to URL: /merchant-gui/list-merchant
+ Zed: perform search by: ${merchant_name}
+ Zed: click Action Button in a table for row that contains: ${merchant_name} Activate
+ Zed: click Action Button in a table for row that contains: ${merchant_name} Approve Access
+ END
+
+Zed: update Merchant on edit page with the following data:
+ [Arguments] @{args}
+ ${merchantData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${zed_create_merchant_name_field}
+ FOR ${key} ${value} IN &{merchantData}
+ IF '${key}'=='merchant name' and '${value}' != '${EMPTY}' Run Keywords
+ ... Type Text ${zed_create_merchant_name_field} ${value}
+ ... AND Set Test Variable ${zedMerchantNewName} ${value}
+ IF '${key}'=='merchant reference' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_reference_field} ${value}
+ IF '${key}'=='e-mail' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_email_field} ${value}
+ IF '${key}'=='store' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='store 2' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='store 3' and '${value}' != '${EMPTY}' Zed: Check checkbox by Label: ${value}
+ IF '${key}'=='uncheck store' and '${value}' != '${EMPTY}' Zed: Uncheck Checkbox by Label: ${value}
+ IF '${key}'=='uncheck store 2' and '${value}' != '${EMPTY}' Zed: Uncheck Checkbox by Label: ${value}
+ IF '${key}'=='uncheck store 3' and '${value}' != '${EMPTY}' Zed: Uncheck Checkbox by Label: ${value}
+ IF '${key}'=='en url' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_url_en_locale_field} ${value}
+ IF '${key}'=='de url' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_url_de_locale_field} ${value}
+ END
+ Zed: submit the form
+ ${form_submitted}= Run Keyword And Ignore Error Page Should Not Contain Element ${zed_create_merchant_email_field} 1s
+ IF 'FAIL' in $form_submitted
+ Reload
+ Zed: submit the form
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Zed: table should contain: search_key=${zedMerchantNewName} error_message=Merchant Profile Update Failed! Form does not submit
+
+Zed: update Merchant name on edit page:
+ [Arguments] ${zedMerchantNewName}
+ Wait Until Element Is Visible ${zed_create_merchant_name_field}
+ Type Text ${zed_create_merchant_name_field} ${zedMerchantNewName}
+ Zed: submit the form
+ Zed: wait for button in Header to be visible: Add Merchant ${browser_timeout}
+ Zed: table should contain: ${zedMerchantNewName}
+
+Zed: create new Merchant User with the following data:
+ [Arguments] @{args}
+ ${merchantUerData}= Set Up Keyword Arguments @{args}
+ Zed: go to tab by link href that contains: merchant-user
+
+ Click ${zed_add_merchant_user_button}
+ Wait Until Element Is Visible ${zed_create_merchant_user_email_field}
+ FOR ${key} ${value} IN &{merchantUerData}
+ IF '${key}'=='e-mail' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_email_field} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_last_name_field} ${value}
+ END
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_table_locator}
+
+Zed: create dynamic merchant user:
+ [Arguments] ${merchant} ${merchant_user_email}=${EMPTY} ${merchant_user_first_name}=FirstRobot ${merchant_user_last_name}=LastRobot ${merchant_user_password}=${default_secure_password} ${merchant_user_group}=${EMPTY} ${zed_admin_email}=${EMPTY}
+ ${dynamic_admin_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ ${unique}= Generate Random String 5 [NUMBERS]
+ ${merchant_value}= Convert To Lower Case ${merchant}
+
+ IF 'spryker' in '${merchant_value}'
+ VAR ${merchant_key} spryker
+ ELSE IF 'king' in '${merchant_value}'
+ VAR ${merchant_key} king
+ ELSE IF 'budget' in '${merchant_value}'
+ VAR ${merchant_key} budget
+ ELSE IF 'expert' in '${merchant_value}'
+ VAR ${merchant_key} expert
+ END
+
+ IF '${zed_admin_email}' == '${EMPTY}'
+ IF ${dynamic_admin_exists}
+ VAR ${zed_admin_email} ${dynamic_admin_user}
+ ELSE
+ Create dynamic admin user in DB
+ VAR ${zed_admin_email} ${dynamic_admin_user}
+ END
+ END
+
+ IF '${merchant_user_email}' == '${EMPTY}'
+ VAR ${merchant_user_email} sonia+merchant+${merchant_key}+${unique}@spryker.com
+ VAR ${dynamic_merchant_user} ${merchant_user_email} scope=TEST
+ ELSE
+ VAR ${dynamic_merchant_user} ${merchant_user_email} scope=TEST
+ END
+
+ ${spryker_merchant_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_spryker_merchant}
+ ${king_merchant_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_king_merchant}
+ ${budget_merchant_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_budget_merchant}
+ ${expert_merchant_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_expert_merchant}
+
+ IF 'spryker' in '${merchant_value}'
+ IF ${spryker_merchant_exists}
+ VAR ${dynamic_spryker_second_merchant} ${merchant_user_email} scope=TEST
+ ELSE
+ VAR ${dynamic_spryker_merchant} ${merchant_user_email} scope=TEST
+ END
+ END
+ IF 'king' in '${merchant_value}'
+ IF ${king_merchant_exists}
+ VAR ${dynamic_king_second_merchant} ${merchant_user_email} scope=TEST
+ ELSE
+ VAR ${dynamic_king_merchant} ${merchant_user_email} scope=TEST
+ END
+ END
+ IF 'budget' in '${merchant_value}'
+ IF ${budget_merchant_exists}
+ VAR ${dynamic_budget_second_merchant} ${merchant_user_email} scope=TEST
+ ELSE
+ VAR ${dynamic_budget_merchant} ${merchant_user_email} scope=TEST
+ END
+ END
+ IF 'expert' in '${merchant_value}'
+ IF ${expert_merchant_exists}
+ VAR ${dynamic_expert_second_merchant} ${merchant_user_email} scope=TEST
+ ELSE
+ VAR ${dynamic_expert_merchant} ${merchant_user_email} scope=TEST
+ END
+ END
+
+ Reload
+ ${currentURL}= Get Location
+ IF '/list-merchant' not in '${currentURL}'
+ ${adminIsLoggedIn}= Zed: is admin user is logged in
+ IF not ${adminIsLoggedIn} Zed: login on Zed with provided credentials: ${zed_admin_email}
+ Zed: go to URL: /merchant-gui/list-merchant
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ TRY
+ Zed: click Action Button in a table for row that contains: ${merchant} Edit
+ EXCEPT
+ # Retry once, in case of a transient issue
+ Zed: go to URL: /merchant-gui/list-merchant
+ Zed: click Action Button in a table for row that contains: ${merchant} Edit
+ END
+ TRY
+ Zed: Check checkbox by Label: Active
+ EXCEPT
+ # Retry once, in case of a transient issue
+ Zed: go to URL: /merchant-gui/list-merchant
+ Zed: click Action Button in a table for row that contains: ${merchant} Edit
+ Zed: Check checkbox by Label: Is Active
+ END
+ Zed: go to tab by link href that contains: merchant-user
+ Click and retry if 5xx occurred: ${zed_add_merchant_user_button}
+ Wait Until Element Is Visible ${zed_create_merchant_user_email_field}
+ Type Text ${zed_create_merchant_user_email_field} ${merchant_user_email}
+ Type Text ${zed_create_merchant_user_first_name_field} ${merchant_user_first_name}${unique}
+ Type Text ${zed_create_merchant_user_last_name_field} ${merchant_user_last_name}${unique}
+ Zed: submit the form
+ TRY
+ Wait Until Element Is Visible ${zed_table_locator}
+ EXCEPT
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_table_locator}
+ END
+ TRY
+ Zed: click Action Button in Merchant Users table for row that contains: ${merchant_user_email} Activate
+ EXCEPT
+ Log Activation button not found
+ END
+ Zed: table should contain non-searchable value: Active
+ Zed: table should contain non-searchable value: Deactivate
+ Zed: table should contain non-searchable value: Delete
+ IF '${merchant_user_group}' != '${EMPTY}'
+ Zed: update Zed user:
+ ... || email | password | group ||
+ ... || ${merchant_user_email} | ${merchant_user_password} | ${merchant_user_group} ||
+ ELSE
+ Zed: update Zed user:
+ ... || email | password ||
+ ... || ${merchant_user_email} | ${merchant_user_password} ||
+ END
+
+Zed: delete merchant user:
+ # TODO: get rid of merchant variable by b2c b2b mapping, like office kind -> video king
+ [Arguments] ${merchant_user} ${merchant}=${EMPTY} ${zed_admin_email}=${EMPTY}
+ ${dynamic_admin_exists}= Run Keyword And Return Status Variable Should Exist ${dynamic_admin_user}
+ ${unique}= Generate Random String 5 [NUMBERS]
+
+ IF '${zed_admin_email}' == '${EMPTY}'
+ IF ${dynamic_admin_exists}
+ VAR ${zed_admin_email} ${dynamic_admin_user}
+ ELSE
+ VAR ${zed_admin_email} ${admin_email}
+ END
+ END
+
+ IF '${merchant}' == '${EMPTY}'
+ IF '+spryker+' in '${merchant_user}'
+ VAR ${merchant} Spryker
+ ELSE IF '+king+' in '${merchant_user}'
+ VAR ${merchant} King
+ ELSE IF '+budget+' in '${merchant_user}'
+ VAR ${merchant} Budget
+ ELSE IF '+expert+' in '${merchant_user}'
+ VAR ${merchant} Experts
+ END
+ END
+
+ Reload
+ ${currentURL}= Get Location
+
+ IF '/list-merchant' not in '${currentURL}'
+ ${adminIsLoggedIn}= Zed: is admin user is logged in
+ IF not ${adminIsLoggedIn} Zed: login on Zed with provided credentials: ${zed_admin_email}
+ Go To ${zed_url}merchant-gui/list-merchant
+ END
+ TRY
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+ Zed: click Action Button in a table for row that contains: ${merchant} Edit
+ Zed: go to tab by link href that contains: merchant-user
+ Zed: click Action Button in Merchant Users table for row that contains: ${merchant_user} Delete
+ Zed: submit the form
+
+Zed: update Merchant User on edit page with the following data:
+ [Arguments] @{args}
+ ${merchantUerData}= Set Up Keyword Arguments @{args}
+ Wait Until Element Is Visible ${zed_create_merchant_user_first_name_field}
+ FOR ${key} ${value} IN &{merchantUerData}
+ IF '${key}'=='e-mail' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_email_field} ${value}
+ IF '${key}'=='first name' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_first_name_field} ${value}
+ IF '${key}'=='last name' and '${value}' != '${EMPTY}' Type Text ${zed_create_merchant_user_last_name_field} ${value}
+ END
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_table_locator}
+
+Zed: perform Merchant User search by:
+ [Arguments] ${search_key}
+ # Build two safe regex fragments:
+ # - enc1: URL-encoded with %20 for spaces
+ # - enc2: URL-encoded with + for spaces
+ ${enc1}= Evaluate re.escape(urllib.parse.quote("""${search_key}""")) modules=re,urllib.parse
+ ${enc2}= Evaluate re.escape(urllib.parse.quote_plus("""${search_key}""")) modules=re,urllib.parse
+ # JS RegExp literal (case-insensitive) for the Merchant User table path + full search[value]
+ ${search_matcher}= Set Variable /merchant-user-gui\/index\/table.*[?&]search%5Bvalue%5D=(?:${enc1}|${enc2})(?:&|$)/i
+ Wait Until Page Contains Element ${zed_table_locator}
+ Clear Text ${zed_merchant_user_search_field_locator}
+ TRY
+ # Create the waiter BEFORE typing to avoid race conditions
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_merchant_user_search_field_locator} ${search_key}
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ IF '${result}[0]'=='FAIL' Log Search by MU event failed level=WARN
+ EXCEPT
+ Log Search event is not fired
+ END
+ # Let the table settle
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Zed: click Action Button in Merchant Users table for row that contains:
+ [Arguments] ${row_content} ${zed_table_action_button_locator}
+ Zed: perform merchant user search by: ${row_content}
+ wait until element is visible xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
+ Click and retry if 5xx occurred: xpath=//table[contains(@class,'dataTable')]/tbody//td[contains(text(),'${row_content}')]/../td[contains(@class,'column-Action') or contains(@class,'column-action')]/*[contains(.,'${zed_table_action_button_locator}')]
diff --git a/atest/testdata/performance/resources/steps/zed_order_steps.robot b/atest/testdata/performance/resources/steps/zed_order_steps.robot
new file mode 100644
index 0000000..771afb3
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_order_steps.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../../resources/common/common_yves.robot
+Resource ../../resources/pages/zed/zed_shipment_page.robot
+Resource ../../resources/pages/zed/zed_order_shipment_page.robot
+Resource ../../resources/pages/zed/zed_order_details_page.robot
+
+*** Keywords ***
+Zed: Enter shipment details for order:
+ [Arguments] @{args}
+ ${registrationData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{registrationData}
+ IF '${key}'=='fname' Type Text ${shipment_address_first_name} ${value}
+ IF '${key}'=='lname' Type Text ${shipment_address_last_name} ${value}
+ IF '${key}'=='email' Type Text ${shipment_address_email} ${value}
+ IF '${key}'=='Address1' Type Text ${shipment_address_address1} ${value}
+ IF '${key}'=='address2' Type Text ${shipment_address_address2} ${value}
+ IF '${key}'=='city' Type Text ${shipment_address_city} ${value}
+ IF '${key}'=='zipcode' Type Text ${shipment_address_zipcode} ${value}
+ IF '${key}'=='salutation' Select From List By Value ${salutation_shipment_page} ${value}
+ IF '${key}'== 'country' Select From List By Value ${country_create_new_shipment_page} ${value}
+ IF '${key}'== 'shipmentmethod' Select From List By Value ${shipment_method_dropdown_new_shipment_page} ${value}
+ END
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_payment_methods_steps.robot b/atest/testdata/performance/resources/steps/zed_payment_methods_steps.robot
new file mode 100644
index 0000000..b6ed990
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_payment_methods_steps.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Library String
+Resource ../pages/zed/zed_payment_methods_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+
+*** Keywords ***
+Zed: wait for payment method:
+ [Arguments] ${provider} ${name}
+ Try reloading page until element is/not appear: xpath=//table//tr/td[text()='${provider}']/../td[text()='${name}']/..//a[contains(@class,'btn-edit')] true 20 10s
+
+Zed: activate/deactivate payment method:
+ [Arguments] ${provider} ${name} ${activate}=true ${stores}=DE,AT
+ Zed: go to URL: /payment-gui/payment-method
+ Zed: wait for payment method: ${provider} ${name}
+ ${activate}= Convert To String ${activate}
+ ${activate}= Convert To Lower Case ${activate}
+ Click xpath=//table//tr/td[text()='${provider}']/../td[text()='${name}']/..//a[contains(@class,'btn-edit')]
+ IF '${activate}' == 'true' or '${activate}' == 'activate'
+ Zed: check checkbox by label: Is the Payment Method active?
+ ELSE
+ Zed: uncheck checkbox by label: Is the Payment Method active?
+ END
+ Zed: go to tab by link href that contains: store-relation
+ ${storesList}= split string ${stores} ,
+ ${storesListLength}= get length ${storesList}
+ FOR ${index} IN RANGE 0 ${storesListLength}
+ ${store}= get from list ${storesList} ${index}
+ IF '${activate}' == 'true' or '${activate}' == 'activate'
+ Zed: check checkbox by label: ${store}
+ ELSE
+ Zed: uncheck checkbox by label: ${store}
+ END
+ END
+ Zed: submit the form
+ Zed: flash message should be shown: success
diff --git a/atest/testdata/performance/resources/steps/zed_root_menus_steps.robot b/atest/testdata/performance/resources/steps/zed_root_menus_steps.robot
new file mode 100644
index 0000000..ba00760
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_root_menus_steps.robot
@@ -0,0 +1,69 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_root_menus_page.robot
+
+*** Keywords ***
+Zed: verify first navigation root menus
+ ${counter}= Set Variable 1
+ ${first_navigation_count}= Get Element Count ${zed_first_navigation_menus_locator}
+ WHILE ${counter} <= ${first_navigation_count}
+ Log ${counter}
+ Click xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'/') and not (contains(@href,'javascript'))])[${counter}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ TRY
+ ${app_terms_overlay_state}= Page Should Contain Element xpath=//app-terms-and-conditions-dialog/ancestor::div[contains(@class,'overlay-container')] message=Overlay is not displayed timeout=1s
+ Remove element from HTML with JavaScript //app-terms-and-conditions-dialog/ancestor::div[contains(@class,'overlay-container')]
+ EXCEPT
+ Log Overlay is not displayed
+ END
+ Wait Until Element Is Visible locator=${zed_log_out_button} timeout=${browser_timeout} message=Some left navigation menu item throws an error.
+ ${counter}= Evaluate ${counter} + 1
+ END
+
+Zed: verify root menu icons
+ ${counter}= Set Variable 1
+ ${first_navigation_icon_count}= Get Element Count ${zed_root_menu_icons_locator}
+ WHILE ${counter} <= ${first_navigation_icon_count}
+ Log ${counter}
+ Page should contain element xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a/i)[${counter}]
+ ${counter}= Evaluate ${counter} + 1
+ END
+
+Zed: verify second navigation root menus
+ ${counter}= Set Variable 1
+ ${first_navigation_count}= Get Element Count ${zed_second_navigation_menus_locator}
+ WHILE ${counter} <= ${first_navigation_count}
+ ${counter_1}= Set Variable 1
+ Log ${counter}
+ Click Element by xpath with JavaScript (//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')])[${counter}]
+ Wait Until Element Is Visible xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')]/parent::li)[${counter}] timeout=10s
+ ${second_navigation_count}= Get Element Count xpath=((//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')])[${counter}]/ancestor::li//ul[contains(@class,'nav-second-level')]//a)
+ WHILE ${counter_1} <= ${second_navigation_count}
+ ${node_state}= Get Element Attribute xpath=(//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')]/parent::li)[${counter}] class
+ log ${node_state}
+ IF 'active' not in '${node_state}'
+ Click Element by xpath with JavaScript (//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')])[${counter}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ END
+ Click Element by xpath with JavaScript ((//ul[@id='side-menu']/li/a/span[@class='nav-label']/../../a[contains(@href,'javascript')])[${counter}]/ancestor::li//ul[contains(@class,'nav-second-level')]//a)[${counter_1}]
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ EXCEPT
+ Log Page is not loaded
+ END
+ Wait Until Element Is Visible ${zed_log_out_button} timeout=${browser_timeout}
+ Log ${counter_1}
+ ${counter_1}= Evaluate ${counter_1} + 1
+ END
+ Wait Until Element Is Visible ${zed_log_out_button} timeout=${browser_timeout}
+ ${counter}= Evaluate ${counter} + 1
+ END
diff --git a/atest/testdata/performance/resources/steps/zed_store_steps.robot b/atest/testdata/performance/resources/steps/zed_store_steps.robot
new file mode 100644
index 0000000..4eaab85
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_store_steps.robot
@@ -0,0 +1,89 @@
+*** Settings ***
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_store_page.robot
+
+
+*** Keywords ***
+
+Zed: create new Store:
+ [Arguments] @{args}
+ Zed: go to URL: /store-gui/list
+ Zed: click button in Header: Create Store
+ Wait Until Element Is Visible ${zed_store_add_name_input}
+ ${storeData}= Set Up Keyword Arguments @{args}
+ FOR ${key} ${value} IN &{storeData}
+ IF '${key}'=='name' and '${value}' != '${EMPTY}'
+ Type Text ${zed_store_add_name_input} ${value}
+ Click ${zed_store_locale_tab}
+ Wait Until Element Is Visible ${zed_store_default_locale_iso_code}
+ END
+ IF '${key}'=='locale_iso_code' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_store_default_locale_iso_code}
+ Select From List By Label ${zed_store_default_locale_iso_code} ${value}
+ Zed: perform store search by: ${value}
+ Zed: Check checkbox by Value: ${value}
+ Click ${zed_store_currency_tab}
+ END
+ IF '${key}'=='currency_iso_code' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_store_default_currency_iso_code}
+ Select From List By Label ${zed_store_default_currency_iso_code} ${value}
+ END
+ IF '${key}'=='currency_code' and '${value}' != '${EMPTY}'
+ ${currency code}= Set Variable ${value}
+ Zed: perform store search by: ${value}
+ Zed: Check checkbox by Value: ${value}
+ END
+ IF '${key}'=='currency_iso_code2' and '${value}' != '${EMPTY}'
+ Wait Until Element Is Visible ${zed_store_default_currency_iso_code}
+ Select From List By Label ${zed_store_default_currency_iso_code} ${value}
+ END
+ IF '${key}'=='currency_code2' and '${value}' != '${EMPTY}'
+ ${currency code}= Set Variable ${value}
+ Zed: perform store search by: ${value}
+ Zed: Check checkbox by Value: ${value}
+ Click ${zed_store_delivery_region_tab}
+ END
+ IF '${key}'=='store_delivery_region' and '${value}' != '${EMPTY}'
+ Zed: perform store search by: ${value}
+ Zed: Check checkbox by Value: ${value}
+ END
+ IF '${key}'=='store_context_timezone' and '${value}' != '${EMPTY}'
+ Click ${zed_store_context_tab}
+ Zed: store context add timezone: ${value}
+ END
+ END
+ Click ${zed_store_save_button}
+
+Zed: perform store search by:
+ [Arguments] ${search_key}
+ # Build two safe regex fragments for the full term:
+ # - enc1: percent-encoded (spaces -> %20)
+ # - enc2: form-encoded (spaces -> +)
+ ${enc1}= Evaluate re.escape(urllib.parse.quote("""${search_key}""")) modules=re,urllib.parse
+ ${enc2}= Evaluate re.escape(urllib.parse.quote_plus("""${search_key}""")) modules=re,urllib.parse
+
+ # Table-agnostic JS RegExp literal for full search[value] (case-insensitive)
+ ${search_matcher}= Set Variable /[?&]search%5Bvalue%5D=(?:${enc1}|${enc2})(?:&|$)/i
+ Clear Text ${zed_store_search_field}
+ TRY
+ ${promise}= Promise To Wait For Response matcher=${search_matcher} timeout=5s
+ Type Text ${zed_store_search_field} ${search_key}
+ Press Keys ${zed_store_search_field} Enter
+ ${result}= Run Keyword And Ignore Error Wait For ${promise}
+ IF '${result}[0]'=='FAIL' Log Search by store event failed level=WARN
+ EXCEPT
+ Log Search event is not fired
+ END
+ TRY
+ Repeat Keyword 3 Wait For Load State
+ Wait For Load State domcontentloaded
+ EXCEPT
+ Log Page is not loaded
+ END
+
+Zed: store context add timezone:
+ [Arguments] ${timezone}
+ Click ${zed_store_context_add_button}
+ Select From List By Label ${zed_store_context_select} ${timezone}
+
\ No newline at end of file
diff --git a/atest/testdata/performance/resources/steps/zed_users_steps.robot b/atest/testdata/performance/resources/steps/zed_users_steps.robot
new file mode 100644
index 0000000..1599d43
--- /dev/null
+++ b/atest/testdata/performance/resources/steps/zed_users_steps.robot
@@ -0,0 +1,145 @@
+*** Settings ***
+Resource ../pages/zed/zed_delete_user_confirmation_page.robot
+Resource ../common/common_zed.robot
+Resource ../common/common.robot
+Resource ../pages/zed/zed_create_zed_user_page.robot
+Resource ../pages/zed/zed_user_role_page.robot
+Resource ../pages/zed/zed_user_group_page.robot
+
+*** Keywords ***
+Zed: delete Zed user with the following email:
+ [Arguments] ${zed_email}
+ Reload
+ ${currentURL}= Get Location
+ IF '/user' not in '${currentURL}' Zed: go to URL: /user
+ Zed: click Action Button in a table for row that contains: ${zed_email} Delete
+ Wait Until Page Contains Element ${zed_confirm_delete_user_button}
+ Click ${zed_confirm_delete_user_button}
+
+Zed: update Zed user:
+ [Arguments] @{args}
+ ${newUserData}= Set Up Keyword Arguments @{args}
+ Reload
+ ${currentURL}= Get Location
+ IF '/user' not in '${currentURL}' Zed: go to URL: /user
+ ${variable_exists}= Run Keyword And Return Status Variable Should Exist ${oldEmail}
+ IF ${variable_exists}
+ Zed: click Action Button in a table for row that contains: ${oldEmail} Edit
+ ELSE
+ Zed: click Action Button in a table for row that contains: ${email} Edit
+ END
+ ${currentURL}= Get Location
+ TRY
+ Wait Until Element Is Visible ${zed_user_email_field}
+ EXCEPT
+ Go To ${currentURL}
+ Wait For Load State
+ Wait For Load State domcontentloaded
+ IF ${variable_exists}
+ Zed: click Action Button in a table for row that contains: ${oldEmail} Edit
+ ELSE
+ Zed: click Action Button in a table for row that contains: ${email} Edit
+ END
+ END
+ Wait Until Element Is Visible ${zed_user_email_field}
+ ${currentURL}= Get Location
+ FOR ${key} ${value} IN &{newUserData}
+ IF '${key}'=='newEmail' and '${value}' != '${EMPTY}' Type Text ${zed_user_email_field} ${value}
+ IF '${key}'=='password' and '${value}' != '${EMPTY}'
+ Type Text ${zed_user_password_filed} ${value}
+ Type Text ${zed_user_repeat_password_field} ${value}
+ END
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text ${zed_user_first_name_field} ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text ${zed_user_last_name_field} ${value}
+ IF '${key}'=='user_is_warehouse_user' and '${value}' != '${EMPTY}'
+ ${value}= Convert To Lower Case ${value}
+ END
+ IF '${key}'=='user_is_warehouse_user' and '${value}' == 'true'
+ Zed: Check checkbox by Label: This user is a warehouse user
+ END
+ IF '${key}'=='user_is_warehouse_user' and '${value}' == 'false'
+ Zed: Uncheck Checkbox by Label: This user is a warehouse user
+ END
+ IF '${key}'=='group' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='remove group' and '${value}' != '${EMPTY}'
+ Zed: Uncheck Checkbox by Label: ${value}
+ END
+ END
+ Zed: submit the form
+ Disable Automatic Screenshots on Failure
+ ${saved_successfully} Run Keyword And Return Status Page Should Not Contain Element ${zed_user_first_name_field} timeout=1s
+ Restore Automatic Screenshots on Failure
+ IF not ${saved_successfully}
+ Go To ${currentURL}
+ Wait Until Element Is Visible ${zed_user_email_field}
+ FOR ${key} ${value} IN &{newUserData}
+ IF '${key}'=='newEmail' and '${value}' != '${EMPTY}' Type Text ${zed_user_email_field} ${value}
+ IF '${key}'=='password' and '${value}' != '${EMPTY}'
+ Type Text ${zed_user_password_filed} ${value}
+ Type Text ${zed_user_repeat_password_field} ${value}
+ END
+ IF '${key}'=='firstName' and '${value}' != '${EMPTY}' Type Text ${zed_user_first_name_field} ${value}
+ IF '${key}'=='lastName' and '${value}' != '${EMPTY}' Type Text ${zed_user_last_name_field} ${value}
+ IF '${key}'=='user_is_warehouse_user' and '${value}' != '${EMPTY}'
+ ${value}= Convert To Lower Case ${value}
+ END
+ IF '${key}'=='user_is_warehouse_user' and '${value}' == 'true'
+ Zed: Check checkbox by Label: This user is a warehouse user
+ END
+ IF '${key}'=='user_is_warehouse_user' and '${value}' == 'false'
+ Zed: Uncheck Checkbox by Label: This user is a warehouse user
+ END
+ IF '${key}'=='group' and '${value}' != '${EMPTY}'
+ Zed: Check checkbox by Label: ${value}
+ END
+ IF '${key}'=='remove group' and '${value}' != '${EMPTY}'
+ Zed: Uncheck Checkbox by Label: ${value}
+ END
+ END
+ Zed: submit the form
+ END
+ Page Should Not Contain Element ${zed_user_first_name_field} message=The user was not updated, check logs for details timeout=1s
+
+
+Zed: create new role with name:
+ [Documentation] Create a new role.
+ [Arguments] ${name}
+ Zed: go to URL: /acl/role
+ Zed: click button in Header: Add new Role
+ Type Text ${zed_user_role_name} ${name}
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_success_flash_message}
+
+Zed: apply access permissions for user role:
+ [Arguments] ${zed_user_role_bundle_access} ${zed_user_role_controller_access} ${zed_user_role_action_access} ${permission_access}
+ Select From List By Value ${zed_user_role_bundle_locator} ${zed_user_role_bundle_access}
+ Select From List By Value ${zed_user_role_controller_locator} ${zed_user_role_controller_access}
+ Select From List By Value ${zed_user_role_action_locator} ${zed_user_role_action_access}
+ Select From List By Label ${zed_user_role_permission} ${permission_access}
+ Click ${zed_user_add_rule_button}
+
+Zed: create new group with role assigned:
+ [Arguments] ${group_name} ${role_name}
+ Zed: go to URL: /acl/group
+ Zed: click button in Header: Create Group
+ Type Text ${zed_user_group_title} ${group_name}
+ Type Text ${zed_user_group_assigned_role_textbox} ${role_name}
+ Keyboard Key Press Enter
+ Zed: submit the form
+ Wait Until Element Is Visible ${zed_success_flash_message}
+
+Zed: validate the message when permission is restricted:
+ [Arguments] ${message}
+ Element Text Should Be ${zed_attribute_access_denied_header} ${message}
+
+Zed: deactivate the created user:
+ [Arguments] ${email}
+ Zed: go to URL: /user
+ Zed: click Action Button in a table for row that contains: ${email} Deactivate
+ Wait Until Element Is Visible ${zed_success_flash_message}
+
+ Zed: assign warehouse to user:
+ [Arguments] ${email}
+ Zed: go to URL: /user
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/negative.robot b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/negative.robot
new file mode 100644
index 0000000..872757c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/negative.robot
@@ -0,0 +1,396 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_product_abstract_collection_with_invalid_query_parameter:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=test
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+
+Create_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH INVALID CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_correct_child_and_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}, {"fk_tax_set": 1, "attributes": "FOO1", "sku": "FOO1", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR1", "sku": "FOOBAR1"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ And Response body parameter should be: [data][0][sku] FOO1
+ And Response body parameter should be: [data][0][attributes] FOO1
+ ### GET PRODUCT ABSTRACT WITH CHILDREN ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] FOO1
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][id_product] ${id_product}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1310
+ And Response body parameter should be: [0][message] Incomplete Request - missing identifier for `robot-tests-product-abstracts0.robot-tests-products0`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1309
+ And Response body parameter should be: [0][message] Failed to persist the data for `robot-tests-product-abstracts0.robot-tests-products0.sku`. Please verify the provided data and try again. Entry is duplicated.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_country_collection_with_existing_child_entity
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_product_abstract_by_id_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST PRODUCT ABSTRACT ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_product_abstract_collection_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_price_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
diff --git a/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/positive.robot b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/positive.robot
new file mode 100644
index 0000000..7117e3e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/complex/positive.robot
@@ -0,0 +1,345 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+ Get_product_abstract_collection_with_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Delete dynamic entity configuration in Database: robot-tests-product-prices
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ Trigger p&s
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of size in: [data] 422 426
+ And Response should contain the array of a certain size: [data][0] 8
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Each array element of array in response should contain property: [data] id_product_abstract
+ And Each array element of array in response should contain property: [data] sku
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] id_product
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] fk_product_abstract
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of size in: [data] 422 426
+ And Response should contain the array of a certain size: [data][0] 8
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+
+ Get_product_abstract_with_childs_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 8
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 1
+ And Response body parameter should be: [data][id_product_abstract] 130
+ And Response body parameter should be: [data][sku] M21704
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] 130
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 8
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Create_and_update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Create_product_abstract_collection_with_two_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH TWO CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}], "robotTestsProductPrices": [{"fk_price_type": 1, "price": 0}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO2
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR2
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ When Save value to a variable: [data][0][robotTestsProductPrices][0][id_price_product] id_price_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][0][robotTestsProductPrices][0][fk_product_abstract] ${id_product_abstract}
+
+ [Teardown] Run Keywords Delete product_price by id_price_product in Database: ${id_price_product}
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Upsert_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract},"attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][new_to] None
+ And Response body parameter should be: [data][0][color_code] None
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_publish_complex_product_with_child_relations:
+ [Documentation] As the tech dept, we need to adjust this test to check in /catalog-search as well.
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-stock-products spy_stock_product 1 {"identifier":"id_stock_product","fields":[{"fieldName":"id_stock_product","fieldVisibleName":"id_stock_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"quantity","fieldVisibleName":"quantity","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_never_out_of_stock","fieldVisibleName":"is_never_out_of_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_stock","fieldVisibleName":"fk_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-localized-attributes spy_product_localized_attributes 1 {"identifier":"id_product_attributes","fields":[{"fieldName":"id_product_attributes","fieldVisibleName":"id_product_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-stores spy_product_abstract_store 1 {"identifier":"id_product_abstract_store","fields":[{"fieldName":"id_product_abstract_store","fieldVisibleName":"id_product_abstract_store","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relations spy_product_relation 1 {"identifier":"id_product_relation","fields":[{"fieldName":"id_product_relation","fieldVisibleName":"id_product_relation","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_relation_type","fieldVisibleName":"fk_product_relation_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_rebuild_scheduled","fieldVisibleName":"is_rebuild_scheduled","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"product_relation_key","fieldVisibleName":"product_relation_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"query_set_data","fieldVisibleName":"query_set_data","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relation-stores spy_product_relation_store 1 {"identifier":"id_product_relation_store","fields":[{"fieldName":"id_product_relation_store","fieldVisibleName":"id_product_relation_store","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_relation","fieldVisibleName":"fk_product_relation","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-products spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-stores spy_price_product_store 1 {"identifier":"id_price_product_store","fields":[{"fieldName":"id_price_product_store","fieldVisibleName":"id_price_product_store","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_currency","fieldVisibleName":"fk_currency","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_price_product","fieldVisibleName":"fk_price_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"gross_price","fieldVisibleName":"gross_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"net_price","fieldVisibleName":"net_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-defaults spy_price_product_default 1 {"identifier":"id_price_product_default","fields":[{"fieldName":"id_price_product_default","fieldVisibleName":"id_price_product_default","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_product_store","fieldVisibleName":"fk_price_product_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-label-product-abstracts spy_product_label_product_abstract 1 {"identifier":"id_product_label_product_abstract","fields":[{"fieldName":"id_product_label_product_abstract","fieldVisibleName":"id_product_label_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_label","fieldVisibleName":"fk_product_label","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-image-sets spy_product_image_set 1 {"identifier":"id_product_image_set","fields":[{"fieldName":"id_product_image_set","fieldVisibleName":"id_product_image_set","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-stores robotTestsProductAbstractStores fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-relations robotTestsProductRelations fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-relations robot-tests-product-relation-stores robotTestsProductRelationStores fk_product_relation id_product_relation
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-price-products robotTestsProductAbstractPriceProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-price-products robot-tests-price-product-stores robotTestsPriceProductStores fk_price_product id_price_product
+ Create dynamic entity configuration relation in Database: robot-tests-price-product-stores robot-tests-price-product-defaults robotTestsPriceProductStoreDefaults fk_price_product_store id_price_product_store
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-categories robotTestsProductAbstractCategories fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-label-product-abstracts robotTestsProductLabelProductAbstracts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-image-sets robotTestsProductImageSets fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-searches robotTestsProductSearch fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-stock-products robotTestsProductStocks fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-localized-attributes robotTestsProductLocalizedAttributes fk_product id_product
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH STOCK ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":2,"attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec","color_code":"#DC2E09","robotTestsProductAbstractProducts":[{"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1 test attributes","is_active":1,"is_quantity_splittable":1,"sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","robotTestsProductSearch":[{"fk_locale":66,"is_searchable":1}, {"fk_locale":46,"is_searchable":1}],"robotTestsProductStocks":[{"fk_stock":1,"is_never_out_of_stock":1,"quantity":10}],"robotTestsProductLocalizedAttributes":[{"fk_locale":66,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}],"robotTestsProductAbstractStores":[{"fk_store":1}],"robotTestsProductRelations":[{"fk_product_relation_type":1,"is_active":1,"is_rebuild_scheduled":1,"product_relation_key":"Prk-d04e93a4-29ea-4c48-96ab-e87416aefbec","query_set_data":"","robotTestsProductRelationStores":[{"fk_store":1}]}],"robotTestsProductAbstractPriceProducts":[{"fk_price_type":1,"price":1000,"robotTestsPriceProductStores":[{"fk_currency":93,"fk_store":1,"gross_price":9999,"net_price":8999,"robotTestsPriceProductStoreDefaults":[{}]}]}],"robotTestsProductAbstractCategories":[{"fk_category":5,"product_order":16}],"robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"},{"fk_locale":46,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"}],"robotTestsProductLabelProductAbstracts":[{"fk_product_label":1}],"robotTestsProductImageSets":[{"fk_locale":66,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}]}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Save value to a variable: [data][0][sku] abstract_sku
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][sku] concrete_sku
+ Trigger p&s
+ Trigger p&s
+ Trigger p&s
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /abstract-products/${abstract_sku}/abstract-product-availabilities
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] d04e93a4-29ea-4c48-96ab-e87416aefbec
+
+ I set Headers: Content-Type=application/vnd.api+json Accept=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /concrete-products/${concrete_sku}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ And Response body parameter should be: [data][attributes][sku] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-searches?filter[product-searches.fk_product]=${id_product}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][0][id_product_search] id_product_search_first
+ And Save value to a variable: [data][1][id_product_search] id_product_search_second
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-searches {"data": [{"id_product_search": ${id_product_search_first},"is_searchable": 0}, {"id_product_search": ${id_product_search_second},"is_searchable": 0}]}
+ Then Response status code should be: 200
+ Trigger p&s
+ Trigger p&s
+ [Teardown] Run Keywords Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductSearch
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductStocks
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductImageSets
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLabelProductAbstracts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractCategories
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStoreDefaults
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractPriceProducts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelationStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelations
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-image-sets
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-label-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-categories
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-defaults
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relation-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relations
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
+ ... AND Delete dynamic entity configuration in Database: robot-tests-stock-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
diff --git a/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/negative.robot b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/negative.robot
new file mode 100644
index 0000000..189c3a1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/negative.robot
@@ -0,0 +1,451 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_list_of_country_with_invalid_token
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID TOKEN ###
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_prefix
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE PREFIX ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity-invalid/robot-test-countries
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE NAME ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/invalid-resource
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/countries/9999999
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_body
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY BODY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_json
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY JSON ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {"data": []}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_valid_and_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}, {"iso2_code":"XX", "iso3_code":"XXX", "name":"Country XXX"}]}
+ Then Response status code should be: 201
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ And Response body parameter should contain: [data][0][iso2_code] XX
+ And Response body parameter should contain: [data][0][iso3_code] XXX
+ When Save value to a variable: [data][0][id_country] country_id
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID RESOURCE NAME ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/cnt {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 404
+ And Response body parameter should contain: [0][message] Not found
+ And Response body parameter should be: [0][code] 007
+ And Response body parameter should contain: [0][status] 404
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_field_value
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID FIELD VALUE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"X","iso3_code":"XXXX","name":""}]}
+ Then Response status code should be: 400
+ And Response should contain the array of a certain size: $ 3
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should contain: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries0` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should contain: [1][status] 400
+ And Response body parameter should contain: [2][message] Invalid data value `robot-test-countries0` for field: `name`.
+ And Response body parameter should be: [2][code] 1306
+ And Response body parameter should contain: [2][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: X
+
+Create_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url", "fk_locale": 46}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] XXA
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] XXB
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XXXX"}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_collection_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY COLLECTION WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XXXX"},{"id_country":${xxb_country_id},"iso3_code":"XXXXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries1` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should be: [1][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field_type
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID FILELD TYPE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name": "FOO", "iso2_code":1234, "iso3_code": 1234}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data type `robot-test-countries0` for field `iso2_code`
+ And Response body parameter should be: [0][code] 1305
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Upsert_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### UDATE WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/1000 {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Entity `robot-test-countries0.id_country: 1000` not found by identifier, and new identifier can not be persisted. Please update the request.
+ And Response body parameter should be: [0][code] 1308
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Delete_country_by_id_is_deletable_false:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": false,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_is_deletable_null:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": null,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_without_is_deletable:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
diff --git a/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/positive.robot b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/positive.robot
new file mode 100644
index 0000000..c4373ce
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/bapi/dynamic_entity/positive.robot
@@ -0,0 +1,578 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/api_dynamic_entity_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_country_collection
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 6
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] iso3_code ZMB
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_Collection_with_filter_first_item
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER FIRST ITEM ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=AC
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=UA
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_multiple_filter_fields
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}&filter[countries.postal_code_mandatory]=1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter_in_condition
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code AE
+ And Array in response should contain property with value: [data] iso3_code ARE
+ And Array in response should contain property with value: [data] name United Arab Emirates
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_invalid_multiple_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"], "not in": ["AT"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=234&page[limit]=2
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property: [data] iso2_code
+ And Each array element of array in response should contain property: [data] iso3_code
+ And Each array element of array in response should contain property: [data] name
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations_out_of_items
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS OUT OF ITEMS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=500&page[limit]=10
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+
+Get_country_collection_with_short_configuration
+ ### SETUP DYNAMIC ENTITY CONFIGURATION WITH LESS NUMBER OF FIELDS ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH SHORT CONFIGURATION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 3
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_by_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request with data: /token 'grantType=password&username=admin@spryker.com&password=change123'
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+ When Save value to a variable: [access_token] token
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should not be EMPTY: [data][iso2_code]
+ And Response body parameter should not be EMPTY: [data][iso3_code]
+ And Response body parameter should not be EMPTY: [data][name]
+ And Response body parameter should not be EMPTY: [data][postal_code_mandatory]
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_and_update_country:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XM
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XM","iso3_code":"XXM","name":"POST XM"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XM
+ And Response body parameter should be: [data][0][iso3_code] XXM
+ And Response body parameter should be: [data][0][name] POST XM
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ ### UPDATE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ ### UPDATE ONE FIELD OF COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name":"Test Country"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Test Country
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Test Country
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XM
+
+Create_and_update_url:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST URL AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: /test-url/123
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"/test-url/123", "fk_locale": 46}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][url] /test-url/123
+ And Response body parameter should be: [data][0][fk_locale] 46
+ When Save value to a variable: [data][0][id_url] id_url
+ ### UPDATE URL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls/${id_url} {"data":{"url":"/test-url-test/42"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ And Response body parameter should be: [data][id_url] ${id_url}
+ ### GET URL AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-urls/${id_url}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: /test-url-test/42
+
+Create_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Create_country_collection_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Upsert_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ Delete country by iso2_code in Database: XL
+ Delete country by iso2_code in Database: XS
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XAA","name":"PUT XAA"},{"iso2_code":"XB","iso3_code":"XBB","name":"PUT XBB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] PUT XAA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] PUT XBB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ When Save value to a variable: [data][0][id_country] xaa_country_id
+ When Save value to a variable: [data][1][id_country] xbb_country_id
+
+ ## UPSERT ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ ### PARTIAL UPDATE ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXL"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Country XXL
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXL
+ ### UPSERT COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xaa_country_id},"iso2_code":"XL","iso3_code":"XXL","name":"XXL"},{"id_country":${xbb_country_id},"iso2_code":"XS","iso3_code":"XXS","name":"XXS"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XL
+ And Response body parameter should be: [data][0][iso3_code] XXL
+ And Response body parameter should be: [data][0][name] XXL
+ And Response body parameter should be: [data][0][id_country] ${xaa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XS
+ And Response body parameter should be: [data][1][iso3_code] XXS
+ And Response body parameter should be: [data][1][name] XXS
+ And Response body parameter should be: [data][1][id_country] ${xbb_country_id}
+ ### GET COUNTRIES AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XL
+ And Response body parameter should be: [data][iso3_code] XXL
+ And Response body parameter should be: [data][name] XXL
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xbb_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XS
+ And Response body parameter should be: [data][iso3_code] XXS
+ And Response body parameter should be: [data][name] XXS
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XL
+ ... AND Delete country by iso2_code in Database: XS
+
+Delete_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_country_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][0][iso2_code] XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_id
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] ${xxa_iso2_code}
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `robot-test-countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Authorization_by_x_api_key
+ [Documentation] data excahnge api should support 2 autorization options: by x-api-key and by backoffice user token.
+ [Setup] Create api key in db
+ When I set Headers: x-api-key=${dummy_api_key}
+ And I send a GET request: /dynamic-entity/categories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ [Teardown] Delete api key from db
+
+Availability_recalculation_after_stock_update
+ [Documentation] checks that product availability is recalculated after stock update via data exchange api
+ [Setup] Find first available product via data exchange api
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/stock-products/${index} {"data":{"is_never_out_of_stock":false,"quantity":0}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][is_never_out_of_stock] False
+ And Response body parameter should be: [data][quantity] 0
+ Trigger p&s
+ And Product availability status should be changed on: is_available=False
+ [Teardown] Run Keywords Remove Tags *
+ ... AND Set Tags bapi
+ ... AND Restore product initial stock via data exchange api:
diff --git a/atest/testdata/performance/tests/api/b2b/dynamic_store/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/b2b/dynamic_store/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..c86691e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/dynamic_store/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue
+
+*** Test Cases ***
+# SEARCH PARAMETERS #
+
+
+Search_by_abstract_sku_per_store
+ [Tags] dms-on
+ When I set Headers: store=DE
+ Then I send a GET request: /catalog-search?q=${abstract.alternative_products.product_1.sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${abstract.alternative_products.product_1.price_de}
+ When I set Headers: store=AT
+ Then I send a GET request: /catalog-search?q=${abstract.alternative_products.product_1.sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${abstract.alternative_products.product_1.price_at}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
new file mode 100644
index 0000000..bde8d03
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product alternative-products
+
+
+*** Test Cases ***
+Get_alternative_abstract_with_nonexistant_SKU
+ When I send a GET request: /concrete-products/fake/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_with_abstract_SKU
+ When I send a GET request:
+ ... /concrete-products/${abstract.alternative_products.product_1.sku}/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_without_SKU
+ When I send a GET request: /concrete-products//abstract-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
new file mode 100644
index 0000000..c2df49d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
@@ -0,0 +1,64 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product alternative-products
+
+
+*** Test Cases ***
+Product_has_abstract_alternative
+ When I send a GET request:
+ ... /concrete-products/${concrete.alternative_products.product_1.sku}/abstract-alternative-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body parameter should have datatype: [data][0][attributes][name] str
+ And Response body parameter should be:
+ ... [data][0][attributes][sku]
+ ... ${abstract.alternative_products.product_2.sku}
+ And Response body has correct self link
+
+Product_has_abstract_alternative_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /concrete-products/${concrete.alternative_products.product_1.sku}/abstract-alternative-products?include=abstract-product-image-sets,abstract-product-availabilities,abstract-product-prices,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body has correct self link
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-image-sets][data]
+ ... 1
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-availabilities][data]
+ ... 1
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-prices][data]
+ ... 1
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][category-nodes][data]
+ ... 1
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: abstract-product-prices
+
+Product_has_no_abstract_alternative
+ When I send a GET request:
+ ... /concrete-products/${bundle_product.product_2.concrete_sku}/abstract-alternative-products
+ Then Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ And Response reason should be: OK
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
new file mode 100644
index 0000000..af67dda
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product inventory-management
+
+
+*** Test Cases ***
+Get_abstract_availability_by_concrete_SKU
+ When I send a GET request:
+ ... /abstract-products/${concrete.alternative_products.product_1.sku}/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
new file mode 100644
index 0000000..1451387
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
@@ -0,0 +1,74 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product inventory-management
+
+
+*** Test Cases ***
+Product_is_available_with_stock_and_never_out_of_stock
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_stock_and_never_out_of_stock_sku_2}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${abstract.available_products.with_stock_and_never_out_of_stock_sku_2}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_with_stock
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_stock.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_never_out_of_stock
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_no_stock_and_never_out_of_stock_sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${abstract.available_products.with_no_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_unavailable
+ When I send a GET request:
+ ... /abstract-products/${abstract.unavailable_product_sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract.unavailable_product_sku}
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_available_with_3_concrete_stocks_combined
+ #checks that stock of all 3 concretes as aggregated in response
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_3_concretes.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
new file mode 100644
index 0000000..2108716
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Get_abstract_image_stes_by_concrete_SKU
+ When I send a GET request:
+ ... /abstract-products/${concrete.alternative_products.product_1.sku}/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
new file mode 100644
index 0000000..0c03e73
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product inventory-management
+
+
+*** Test Cases ***
+Abstract_image_sets_with_1_concrete
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_stock_and_never_out_of_stock_sku}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${abstract.available_products.with_stock_and_never_out_of_stock_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
+
+Abstract_image_sets_with_3_concretes
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_3_concretes.sku}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
new file mode 100644
index 0000000..c790587
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
@@ -0,0 +1,52 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product prices
+
+
+*** Test Cases ***
+Get_abstract_prices_by_concrete_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${concrete.alternative_products.product_1.sku}/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_by_fake_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/fake/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_with_missing_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products//abstract-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_abstract_prices_with_missing_token
+ When I send a GET request: /abstract-products/${abstract.original_prices.sku}/abstract-product-prices
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_abstract_prices_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=fake
+ When I send a GET request: /abstract-products/${abstract.original_prices.sku}/abstract-product-prices
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
new file mode 100644
index 0000000..59dc7f9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
@@ -0,0 +1,131 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product prices
+
+
+*** Test Cases ***
+Abstract_prices_detault_only
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_3_concretes.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][prices][0][currency][symbol]
+ ... ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Abstract_prices_detault_only_CHF
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_3_concretes.sku}/abstract-product-prices?currency=CHF&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][prices][0][currency][symbol]
+ ... ${currency.chf.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Abstract_volume_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract.volume_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.volume_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][prices][0][currency][symbol]
+ ... ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... grossAmount
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... netAmount
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... quantity
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][prices][0][volumePrices][0][grossAmount]
+ ... 1
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][prices][0][volumePrices][0][netAmount]
+ ... 1
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][prices][0][volumePrices][0][quantity]
+ ... 1
+ And Response body has correct self link
+
+Abstract_prices_original_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract.original_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.original_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][prices][1][grossAmount]
+ ... ${default_price}
+ And Each array element of array in response should contain property with value:
+ ... [data][0][attributes][prices]
+ ... netAmount
+ ... ${None}
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][prices]
+ ... ${currency.eur.code}
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][prices]
+ ... ${currency.eur.name}
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][prices]
+ ... ${currency.eur.symbol}
+ And Each array element of array in response should contain property with value:
+ ... [data][0][attributes][prices]
+ ... volumePrices
+ ... ${array}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/negative.robot
new file mode 100644
index 0000000..07c4172
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/negative.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Get_abstract_product_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_by_fake_SKU
+ When I send a GET request: /abstract-products/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_with_missing_SKU
+ When I send a GET request: /abstract-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/positive.robot
new file mode 100644
index 0000000..d710e58
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/abstract_product_endpoints/abstract_products/positive.robot
@@ -0,0 +1,201 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product tax product-labels product-options inventory-management
+
+
+*** Test Cases ***
+Abstract_product_with_one_concrete
+ #Bug - CC-16551
+ When I send a GET request: /abstract-products/${abstract.available_products.with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be:
+ ... [data][attributes][name]
+ ... ${abstract.available_products.with_stock.name}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array of a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size:
+ ... [data][attributes][attributeMap][product_concrete_ids]
+ ... 1
+ And Response body parameter should contain:
+ ... [data][attributes][superAttributes]
+ ... ${abstract.available_products.with_stock.superattribute}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_3_concrete3
+ #Bug - CC-16551
+ When I send a GET request: /abstract-products/${abstract.available_products.with_3_concretes.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be:
+ ... [data][attributes][name]
+ ... ${abstract.available_products.with_3_concretes.name}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array of a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size:
+ ... [data][attributes][attributeMap][product_concrete_ids]
+ ... 2
+ And Response body parameter should contain:
+ ... [data][attributes][superAttributes]
+ ... ${abstract.available_products.with_3_concretes.superattribute}
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_abstract_includes_for_availability_images_taxes_categories_and_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_stock.sku}?include=abstract-product-availabilities,abstract-product-image-sets,product-tax-sets,category-nodes,abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be:
+ ... [data][attributes][name]
+ ... ${abstract.available_products.with_stock.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size:
+ ... [data][relationships][abstract-product-image-sets][data]
+ ... 1
+ And Response should contain the array of a certain size:
+ ... [data][relationships][abstract-product-availabilities][data]
+ ... 1
+ And Response should contain the array of a certain size: [data][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][category-nodes][data]
+ ... 1
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][abstract-product-prices][data]
+ ... 0
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: abstract-product-prices
+
+Abstract_product_with_abstract_includes_for_labels
+ [Documentation] https://spryker.atlassian.net/browse/CC-31988
+ [Tags] skip-due-to-refactoring
+ [Setup] Trigger product labels update
+ When I send a GET request: /abstract-products/${abstract.with_label.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.with_label.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract.with_label.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract.with_label.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][product-labels][data]
+ ... 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+# Bug CC-14879
+
+Abstract_product_with_abstract_includes_for_reviews
+ When I send a GET request: /abstract-products/${abstract.with_review.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.with_review.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract.with_review.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract.with_review.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][product-reviews][data]
+ ... 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-reviews
+ And Response include element has self link: product-reviews
+
+Abstract_product_with_abstract_includes_for_options
+ When I send a GET request: /abstract-products/${abstract.with_options.sku}?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.with_options.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract.with_options.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract.with_options.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][product-options][data]
+ ... 0
+ And Response should contain the array larger than a certain size: [included] 1
+ And Response include should contain certain entity type: product-options
+ And Response include element has self link: product-options
+
+Abstract_product_with_3_concrete_and_concrete_nested_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_3_concretes.sku}?include=concrete-products,concrete-product-prices,concrete-product-image-sets,concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${abstract.available_products.with_3_concretes.sku}
+ And Response body parameter should be:
+ ... [data][attributes][name]
+ ... ${abstract.available_products.with_3_concretes.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 2
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include element has self link: concrete-products
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+
+Abstract_product_in_different_locales_languages
+ When I set Headers: Accept-Language=de-DE
+ And I send a GET request: /abstract-products/${abstract.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract.product_in_different_locales.description_de}
+ When I set Headers: Accept-Language=en-US
+ And I send a GET request: /abstract-products/${abstract.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract.product_in_different_locales.description_en}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/negative.robot
new file mode 100644
index 0000000..c074436
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/negative.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+Get_acess_token_with_invalid_password
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":"fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_invalid_email
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"fake@spryker.com","password":"${yves_user.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_empty_password
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+
+Get_acess_token_with_empty_email
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: username => This value should not be blank.
+
+Get_acess_token_with_invalid_type
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_acess_token_with_empty_type
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/positive.robot
new file mode 100644
index 0000000..bf0f1ae
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/access_tokens/positive.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+Get_access_token_for_customer
+ When I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body should contain: idCompanyUser
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/negative.robot
new file mode 100644
index 0000000..1f05050
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/negative.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+#######POST#######
+
+Refresh_token_with_access_token
+ [Setup] I get access token for the customer: ${yves_user.email}
+ When I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_invalid_refresh_token
+ When I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "faketoken"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_empty_refresh_token
+ When I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": ""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: refreshToken => This value should not be blank.
+
+Refresh_token_with_invalid_type
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "access-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Refresh_token_with_deleted_refresh_token
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ ... AND I set Headers: Authorization=Bearer ${access_token}
+ ... AND I send a DELETE request: /refresh-tokens/${refresh_token}
+ ... AND Response status code should be: 204
+ And I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Failed to refresh token.
+
+#######DELETE#######
+# Spryker is designed so removing non-existent refresh token will return 204 for security reasons
+
+Delete_refresh_token_with_invalid_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /refresh-tokens/faketoken
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_refresh_token_with_missing_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_refresh_token_with_no_access_token
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Spryker is designed so that deleting will return 204, but the token will not be removed and can be used (done for security reasons)
+
+Delete_refresh_token_for_another_user
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Authorization=Bearer ${access_token}
+ And I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/positive.robot
new file mode 100644
index 0000000..1d9c91c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/refresh_tokens/positive.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+Refresh_access_token_for_customer
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request:
+ ... /refresh-tokens
+ ... {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Save value to a variable: [data][attributes][accessToken] refreshed_access_token
+ And Response body has correct self link internal
+ When I set Headers: Authorization=Bearer ${refreshed_access_token}
+ And I send a GET request: /customers
+ Then Response status code should be: 200
+
+Delete_refresh_token_for_customer
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I set Headers: Authorization=Bearer ${access_token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/negative.robot
new file mode 100644
index 0000000..f1d57a3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/negative.robot
@@ -0,0 +1,127 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+Get_token_for_customer_with_invalid_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"grant_type": "invalid_grant_type","username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be:
+ ... [error_description]
+ ... The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+Get_token_for_customer_with_missing_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be:
+ ... [error_description]
+ ... The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+Get_token_for_customer_with_invalid_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "wrong_password"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+Get_token_for_customer_with_missing_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.password}","username": "${yves_user.email}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be:
+ ... [error_description]
+ ... The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+Get_token_for_customer_with_invalid_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.password}","username": "fake@spryker.com","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+Get_token_for_customer_with_missing_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.password}","password": "${yves_user.password}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be:
+ ... [error_description]
+ ... The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+Get_token_using_refresh_token_for_customer_with_missing_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be:
+ ... [error_description]
+ ... The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+Get_token_using_refresh_token_for_customer_with_invalid_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data:
+ ... /token
+ ... {"grant_type": "invalid_grant_type","refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be:
+ ... [error_description]
+ ... The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+Get_token_using_refresh_token_for_customer_with_missing_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be:
+ ... [error_description]
+ ... The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+Get_token_using_refresh_token_for_customer_with_invalid_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.refresh_token}","refresh_token": "invalid_refresh_token"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The refresh token is invalid.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/positive.robot
new file mode 100644
index 0000000..1b86a6f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/access_token_endpoints/token/positive.robot
@@ -0,0 +1,39 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl
+
+
+*** Test Cases ***
+Get_token_for_customer
+ I set Headers: Content-Type=${urlencoded_header_content_type}
+ I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ Response status code should be: 200
+ Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+Get_token_using_refresh_token_for_customer
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data:
+ ... /token
+ ... {"grant_type": "${grant_type.refresh_token}","refresh_token": "${refresh_token}"}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/negative.robot
new file mode 100644
index 0000000..43c21a6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/negative.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Get_agent_token_for_user_who_is_not_agent
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_invalid_password
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_non-existent_email
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "fake@spryker.com","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_email
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_password
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_wrong_type
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/positive.robot
new file mode 100644
index 0000000..9fda360
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_access_tokens/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Agent_can_get_access_token
+ When I send a POST request:
+ ... /agent-access-tokens
+ ... {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
new file mode 100644
index 0000000..e4c461f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
@@ -0,0 +1,90 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Agent_cannot_impersonate_customer_with_no_agent_token
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_wrong_token_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_invalid_token
+ [Setup] I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer fake
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Agent_cannot_impersonate_customer_with_wrong_type
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-token","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Agent_cannot_impersonate_customer_with_invalid_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_empty_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_missing_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
new file mode 100644
index 0000000..3c83c09
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
@@ -0,0 +1,55 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Agent_can_get_customer_impersonation_token
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request:
+ ... /agent-customer-impersonation-access-tokens
+ ... {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-customer-impersonation-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
+
+Customer_impersonation_token_can_be_used
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ ... AND I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] impersonation_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${impersonation_token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"name": "cart${random}","priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] cart_uid
+ And I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ And Response status code should be: 201
+ When I get access token for the customer: ${yves_user.email}
+ And I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ Then I send a GET request: /carts/${cart_uid}?include=items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/negative.robot
new file mode 100644
index 0000000..2339f15
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/negative.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Agent_searches_for_customers_with_no_token
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_searches_for_customers_with_customer_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/positive.robot
new file mode 100644
index 0000000..933d652
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/agent_endpoints/agent_customer_search/positive.robot
@@ -0,0 +1,178 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core customer-access acl agent-assist
+
+
+*** Test Cases ***
+Agent_can_get_search_for_customers_without_search_parameters
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 10
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][0][customerReference]
+ ... ${customer_reference.de_1}
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][9][customerReference]
+ ... ${customer_reference.de_10}
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][customers]
+ ... firstName
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][customers]
+ ... lastName
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_first_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.first_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][0][customerReference]
+ ... ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_last_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.last_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][0][customerReference]
+ ... ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_email
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.email}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][0][customerReference]
+ ... ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=so
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 2
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring_and_not_find_any
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=ghjk
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 0
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_with_larger_page_size
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=0&page[limit]=15
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 15
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][0][customerReference]
+ ... ${customer_reference.de_1}
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][14][customerReference]
+ ... ${customer_reference.de_15}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body parameter should not be EMPTY: [links][self]
+
+Agent_can_get_search_for_customers_from_last_page
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=30&page[limit]=10
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 6
+ And Response body parameter should be:
+ ... [data][0][attributes][customers][5][customerReference]
+ ... ${customer_reference.de_34}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][self]
diff --git a/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/negative.robot
new file mode 100644
index 0000000..bdc49c8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/negative.robot
@@ -0,0 +1,160 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+
+*** Test Cases ***
+#GET requests
+
+Get_availability_notifications_without_customerId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers//availability-notifications
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error code: 4606
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_with_invalid_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=325tr
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Authorization=
+ ... AND I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_without_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+
+Subscribe_to_availability_notifications_with_empty_type
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Subscribe_to_availability_notifications_without_type
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Subscribe_to_availability_notifications_with_invalid_sku
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "fake","email": "${yves_user.email}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Each array element of array in response should contain property with value: [errors] code 4601
+ And Each array element of array in response should contain property with value: [errors] status ${404}
+ And Array in response should contain property with value: [errors] detail Product not found.
+
+Subscribe_to_availability_notifications_with_invalid_email
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "gmail"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... email => This value is not a valid email address.
+
+Subscribe_to_availability_notifications_with_empty_sku_and_email
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "","email": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... sku => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... email => This value should not be blank.
+
+Subscribe_to_availability_notifications_without_sku_and_email
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+
+Subscribe_to_availability_notifications_with_existing_subscription
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4602
+ And Response should return error message: Subscription already exists.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+
+Delete_availability_notifications_with_invalid_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/7fc6ebf
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error code: 4603
+ And Response should return error message: "Subscription doesnt exist."
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Delete_availability_notifications_without_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/positive.robot
new file mode 100644
index 0000000..8bcefd1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/availability_notifications/positive.robot
@@ -0,0 +1,90 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+
+*** Test Cases ***
+#GET requests
+
+Get_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be:
+ ... [data][0][attributes][sku]
+ ... ${concrete.alternative_products.product_1.sku}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_empty_list_of_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+#POST requests
+
+Subscribe_to_availability_notifications_for_customer
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][sku] ${concrete.alternative_products.product_1.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Subscribe_to_availability_notifications_with_non_existing_email
+ When I send a POST request:
+ ... /availability-notifications
+ ... {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "sonia+${random}@spryker.com"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] sonia+${random}@spryker.com
+ And Response body parameter should be: [data][attributes][sku] ${concrete.alternative_products.product_1.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+
+Delete_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/${availability_notification_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/negative.robot
new file mode 100644
index 0000000..2f21f77
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+
+*** Test Cases ***
+Retrieves_my_availability_notifications_with_missing_auth_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_my_availability_notifications_with_invalid_auth_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
diff --git a/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/positive.robot
new file mode 100644
index 0000000..42ef4b2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/availability_endpoints/my_availability_notifcations/positive.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+
+*** Test Cases ***
+Get_my_availability_notifications
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete.alternative_products.product_1.sku}","email": "${yves_user.email}"}}}
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be: [data][0][attributes][localeName] ${locale.EN.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be:
+ ... [data][0][attributes][sku]
+ ... ${concrete.alternative_products.product_1.sku}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] localeName
+ And Each array element of array in response should contain nested property: [data] [attributes] email
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/negative.robot
new file mode 100644
index 0000000..909b37a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product-bundles product
+
+
+*** Test Cases ***
+Get_bundled_products_with_nonexisting_concrete_sku
+ [Documentation] bug: https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/fake/bundled-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_bundled_products_with_invalid_concrete_sku
+ [Documentation] bug: https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/:sku/bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_bundled_products_with_missing_concrete_sku
+ When I send a GET request: /concrete-products//bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/positive.robot
new file mode 100644
index 0000000..3aa08c6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/bundle_endpoints/bundled_products/positive.robot
@@ -0,0 +1,120 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product-bundles product
+
+
+*** Test Cases ***
+Get_concrete_bundled_products_inside_concrete_bundle
+ When I send a GET request: /concrete-products/${bundle_product.product_1.concrete_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... bundled-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Response body parameter should be in: [data][0][attributes][sku] ${bundle_product.product_2.concrete_sku} ${bundle_product.product_3.concrete_sku} ${bundle_product.product_4.concrete_sku}
+ And Response body parameter should be in: [data][1][attributes][sku] ${bundle_product.product_2.concrete_sku} ${bundle_product.product_3.concrete_sku} ${bundle_product.product_4.concrete_sku}
+ And Response body parameter should be in: [data][2][attributes][sku] ${bundle_product.product_2.concrete_sku} ${bundle_product.product_3.concrete_sku} ${bundle_product.product_4.concrete_sku}
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... [attributes][quantity]
+ ... ${bundle_product.qty_of_each_product_inside_bundle}
+ And Response body has correct self link
+
+Get_concrete_bundled_products_inside_concrete_bundle_with_included_concretes
+ When I send a GET request:
+ ... /concrete-products/${bundle_product.product_1.concrete_sku}/bundled-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... bundled-products
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... [relationships][concrete-products][data][0][type]
+ ... concrete-products
+ And Response should contain the array of a certain size:
+ ... [included]
+ ... ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+
+Get_concrete_bundle_product_with_bundled_products_include
+ When I send a GET request: /concrete-products/${bundle_product.product_1.concrete_sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.product_1.concrete_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.product_1.concrete_sku}
+ And Response body parameter should be:
+ ... [data][attributes][productAbstractSku]
+ ... ${bundle_product.product_1.abstract_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_1.name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] Yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size:
+ ... [data][relationships][bundled-products][data]
+ ... ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][bundled-products][data]
+ ... type
+ ... bundled-products
+ And Response should contain the array larger than a certain size:
+ ... [included]
+ ... ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_abstract_bundle_product_with_bundled_products_include
+ When I send a GET request:
+ ... /abstract-products/${bundle_product.product_1.abstract_sku}?include=bundled-products,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${bundle_product.product_1.abstract_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.product_1.abstract_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_1.name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] Yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body parameter should be:
+ ... [data][attributes][attributeMap][product_concrete_ids]
+ ... ${bundle_product.product_1.concrete_sku}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 1
+ And Response body parameter should be:
+ ... [data][relationships][concrete-products][data][0][id]
+ ... ${bundle_product.product_1.concrete_sku}
+ And Response should contain the array larger than a certain size:
+ ... [included]
+ ... ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_concrete_bundled_products_for_nonbundle_product
+ When I send a GET request:
+ ... /concrete-products/${concrete.available_product.with_stock_and_never_out_of_stock.sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot
new file mode 100644
index 0000000..2f8e773
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart customer-access spryker-core acl shared-carts
+
+
+*** Test Cases ***
+Get_cart_permission_group_with_unauthenicated_user
+ When I send a GET request: /cart-permission-groups/1
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_cart_permission_group_by_non_exist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/111111
+ Then Response status code should be: 404
+ And Response should return error code: 2501
+ And Response should return error message: Cart permission group not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot
new file mode 100644
index 0000000..acbf01a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot
@@ -0,0 +1,100 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart customer-access spryker-core acl shared-carts multiple-carts
+
+
+*** Test Cases ***
+Get_cart_permission_groups_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] company_user_id
+ ... AND I send a POST request: /carts/${cart_id}/shared-carts {"data": {"type": "shared-carts","attributes": {"idCompanyUser": "${company_user_id}","idCartPermissionGroup": "2"}}}
+ When I send a GET request: /carts/${cart_id}?include=shared-carts,cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][shared-carts]
+ And Each array element of array in response should contain property:
+ ... [data][relationships][shared-carts][data]
+ ... type
+ And Each array element of array in response should contain property:
+ ... [data][relationships][shared-carts][data]
+ ... id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value in:
+ ... [included]
+ ... type
+ ... cart-permission-groups
+ ... shared-carts
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 2
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDefault]
+ And Response body parameter should be in: [included][0][attributes][isDefault] true false
+ And Response body parameter should be: [included][1][type] shared-carts
+ And Response body parameter should be: [included][1][attributes][idCompanyUser] ${company_user_id}
+ And Response body parameter should be: [included][1][attributes][idCartPermissionGroup] 2
+ And Response body parameter should not be EMPTY: [included][1][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property:
+ ... [included][1][relationships][cart-permission-groups][data]
+ ... type
+ And Each array element of array in response should contain property:
+ ... [included][1][relationships][cart-permission-groups][data]
+ ... id
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_all_cart_permission_groups
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... cart-permission-groups
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Each array element of array in response should contain property with value in:
+ ... [data]
+ ... [attributes][isDefault]
+ ... True
+ ... False
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_cart_permission_groups_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/${cart_permission_group_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter Should Be: [data][type] cart-permission-groups
+ And Response body parameter should Be: [data][id] ${cart_permission_group_id}
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][isDefault]
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/negative.robot
new file mode 100644
index 0000000..21ae54d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/negative.robot
@@ -0,0 +1,458 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart customer-access spryker-core
+
+
+*** Test Cases ***
+#GET requests
+
+Get_cart_by_cart_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_cart_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/12345678
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_cart_by_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_customer_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=234567thgf
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_customer_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/user-01/carts
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//carts
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+
+Create_cart_with_invalid_access_token
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_without_access_token
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_cart_with_invalid_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "D","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 112
+ And Response should return error message: Store data is invalid.
+
+Create_cart_with_invalid_priceMod_and_currency
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ And Response body parameter should be: [errors][2][code] 107
+ And Response body parameter should be: [errors][2][detail] Failed to create cart.
+
+Create_cart_with_empty_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": "","name": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... priceMode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... currency => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... store => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... name => This value should not be blank.
+
+Create_cart_without_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... priceMode => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... currency => This field is missing.
+ And Array in response should contain property with value: [errors] detail store => This field is missing.
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+#PATCH requests
+
+Update_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=ETag
+ When I send a PATCH request:
+ ... /carts/not-existing-cart
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Update_cart_without_access_token
+ [Setup] I set Headers: Authorization= If-Match=If-Match=ETag
+ When I send a PATCH request:
+ ... /carts/not-existing-cart
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Update_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/8567km
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${412}
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_from_another_customer_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match="3278654tv3"
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${412}
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${428}
+ And Response reason should be: Precondition Required
+ And Response should return error message: If-Match header is missing.
+ And Response should return error code: 005
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "car","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: name => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "DEK"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+
+Delete_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=iuhiu6gi7
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Delete_cart_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Delete_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/88ca6f79
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Delete_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/positive.robot
new file mode 100644
index 0000000..526fa97
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/carts/positive.robot
@@ -0,0 +1,537 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart prices tax promotions-discounts spryker-core customer-access multiple-carts
+
+
+*** Test Cases ***
+# GET requests
+
+Get_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+# Spryker is designed so that we can get all carts same as for /customers/{customerId}/carts request
+ When I send a GET request: /carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... expenseTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... discountTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... taxTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... subtotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... grandTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... priceToPay
+ And Each array element of array in response should contain nested property: [data] attributes discounts
+ And Each array element of array in response should contain property: [data] links
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_cart_id_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock.product_1.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete.available_product.with_stock.product_1.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] concrete.with_options.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_original_prices.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][2][id] concrete.with_original_prices.id
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][items][data] 3
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][items][data]
+ ... type
+ ... items
+ And Response body parameter should be:
+ ... [data][relationships][items][data][0][id]
+ ... ${concrete.available_product.with_stock.product_1.id}
+ And Response body parameter should be: [data][relationships][items][data][1][id] ${concrete.with_options.id}
+ And Response body parameter should be:
+ ... [data][relationships][items][data][2][id]
+ ... ${concrete.with_original_prices.id}
+ And Response should contain the array of a certain size: [included] 3
+ And Each array element of array in response should contain property with value: [included] type items
+ And Response body parameter should be:
+ ... [included][0][id]
+ ... ${concrete.available_product.with_stock.product_1.id}
+ And Response body parameter should be: [included][1][id] ${concrete.with_options.id}
+ And Response body parameter should be: [included][2][id] ${concrete.with_original_prices.id}
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][2][attributes][sku] ${concrete.with_original_prices.sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 1
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value:
+ ... [included]
+ ... unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value:
+ ... [included]
+ ... unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] salesUnit
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_cart_id_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount.product_1.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] discount.product_1.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount.product_2.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] discount.product_2.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount.product_3.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][2][id] discount.product_3.id
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ #totals
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discounts.discount_1.total_sum_for_products_1_and_2}
+ ... +
+ ... ${discounts.discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ #discounts
+ And Response should contain the array of a certain size: [data][attributes][discounts] 2
+ And Response body parameter should be:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.discount_1.name}
+ And Response body parameter should be:
+ ... [data][attributes][discounts][0][amount]
+ ... ${discounts.discount_1.total_sum_for_products_1_and_2}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be:
+ ... [data][attributes][discounts][1][displayName]
+ ... ${discounts.discount_2.name}
+ And Response body parameter should be:
+ ... [data][attributes][discounts][1][amount]
+ ... ${discounts.discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body has correct self link internal
+ #items
+ And Response should contain the array of a certain size: [data][relationships][items][data] 3
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][items][data]
+ ... type
+ ... items
+ And Response body parameter should be: [data][relationships][items][data][0][id] ${discount.product_1.id}
+ And Response body parameter should be: [data][relationships][items][data][1][id] ${discount.product_2.id}
+ And Response body parameter should be: [data][relationships][items][data][2][id] ${discount.product_3.id}
+ #included
+ And Response should contain the array of a certain size: [included] 3
+ And Each array element of array in response should contain property with value: [included] type items
+ #item 1
+ And Response body parameter should be: [included][0][id] ${discount.product_1.id}
+ And Response body parameter should be: [included][0][attributes][sku] ${discount.product_1.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ ... ${discount.product_1.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ ... ${discount.product_1.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ ... ${discount.product_1.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ ... ${discount.product_1.total_sum_of_discounts}
+ #item 2
+ And Response body parameter should be: [included][1][id] ${discount.product_2.id}
+ And Response body parameter should be: [included][1][attributes][sku] ${discount.product_2.sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ ... ${discount.product_2.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ ... ${discount.product_2.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ ... ${discount.product_2.total_sum_of_discounts}
+ And Response body parameter should be:
+ ... [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ ... ${discount.product_2.total_sum_of_discounts}
+ #item 3
+ And Response body parameter should be: [included][2][id] ${discount.product_3.id}
+ And Response body parameter should be: [included][2][attributes][sku] ${discount.product_3.sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [included][2][attributes][calculations][unitDiscountAmountAggregation]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be:
+ ... [included][2][attributes][calculations][sumDiscountAmountAggregation]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be:
+ ... [included][2][attributes][calculations][unitDiscountAmountFullAggregation]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be:
+ ... [included][2][attributes][calculations][sumDiscountAmountFullAggregation]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property: [data] attributes totals
+ And Each array element of array in response should contain nested property: [data] attributes discounts
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... expenseTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... discountTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... taxTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... subtotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... grandTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... priceToPay
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+
+Create_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response body has correct self link for created entity: ${cart_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_cart_with_existing_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ When I send a POST request:
+ ... /carts
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id_2
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id_2}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response body has correct self link for created entity: ${cart_id_2}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /carts/${cart_id_2}
+ ... AND Response status code should be: 204
+
+#PATCH requests
+
+Update_cart_by_cart_id_with_all_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+# Spryker is designed so that we can send empty attributes: priceMod, currency, store and it will not be changed to the empty values.
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_name_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request:
+ ... /carts/${cart_id}
+ ... {"data": {"type": "carts","attributes": {"name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_existing_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": "My Cart"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] "My Cart"
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+
+Delete_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Array in response should contain property with value: [errors] detail Cart with given uuid not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/negative.robot
new file mode 100644
index 0000000..f9d8322
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/negative.robot
@@ -0,0 +1,424 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart product configurable-product inventory-management
+
+
+*** Test Cases ***
+###### POST #######
+
+Add_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /carts/fake/items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /carts//items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_item_to_cart_with_invalid_token
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} Authorization="fake"
+ When I send a POST request:
+ ... /carts/as/items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_item_to_cart_with_missing_token
+ When I send a POST request:
+ ... /carts/fake/items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "carts","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... sku => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be of type numeric.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### PATCH #######
+
+Update_item_in_cart_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/fake
+ ... {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/fake/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_cart_with_no_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request:
+ ... /carts//items/${item_uid}
+ ... {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/${item_uid}
+ ... {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_without_changing_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/${item_uid}
+ ... {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 114
+ And Response should return error message: Cart item could not be updated.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_with_invalid_parameters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/${item_uid}
+ ... {"data": {"type": "items","attributes": {"quantity": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts/fake/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_with_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts//items/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/positive.robot
new file mode 100644
index 0000000..70f3e7c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/items/positive.robot
@@ -0,0 +1,580 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core cart product product-options non-splittable-products configurable-product promotions-discounts inventory-management
+
+
+*** Test Cases ***
+#####POST#####
+
+Add_one_item_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+# Not sure if it makes any sense: I save id and groupKey to variables and then check them out with them from the same response body
+
+Add_two_items_to_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items?include=items,concrete-products,abstract-products
+ ... {"data":{"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 2}}}
+ Then Save value to a variable:
+ ... [included][2][id]
+ ... concrete.available_product.with_stock_and_never_out_of_stock.id
+ And Save value to a variable:
+ ... [included][2][attributes][groupKey]
+ ... concrete.available_product.with_stock_and_never_out_of_stock.groupKey
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][2][type] items
+ And Response body parameter should be:
+ ... [included][2][id]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.id}
+ And Response body parameter should be:
+ ... [included][2][attributes][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 2
+ And Response body parameter should be:
+ ... [included][2][attributes][groupKey]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.groupKey}
+ And Response body parameter should be:
+ ... [included][2][attributes][abstractSku]
+ ... ${abstract.available_products.with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][2][attributes][calculations][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][2][attributes][salesUnit] None
+ And Response should contain the array of a certain size: [included][2][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Get_a_cart_with_included_items_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 2}}}
+ ... AND Save value to a variable: [included][0][id] concrete.available_product.with_stock_and_never_out_of_stock.id
+ ... AND Save value to a variable: [included][0][attributes][groupKey] concrete.available_product.with_stock_and_never_out_of_stock.groupKey
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_uid}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response body parameter should be: [included][1][type] items
+ And Response body parameter should be:
+ ... [included][1][id]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.id}
+ And Response body parameter should be:
+ ... [included][1][attributes][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 2
+ And Response body parameter should be:
+ ... [included][1][attributes][groupKey]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.groupKey}
+ And Response body parameter should be:
+ ... [included][1][attributes][abstractSku]
+ ... ${abstract.available_products.with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][1][attributes][calculations][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][1][attributes][salesUnit] None
+ And Response should contain the array of a certain size: [included][1][attributes][selectedProductOptions] 0
+
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_five_items_to_cart_with_included_cart_rules_and_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+#If run test on Tuesday or Wendsday it fails because of Cart rule id=2 which applies on certain days of week
+ When I send a POST request:
+ ... /carts/${cart_uid}/items?include=cart-rules,promotional-items
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.with_promotions_sku}","quantity": 5}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array larger than a certain size: [data][relationships][cart-rules][data] 0
+ And Response should contain the array of a certain size: [data][relationships][promotional-items][data] 1
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response should contain the array smaller than a certain size: [included] 5
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: items
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_bundle_to_cart_with_included_bundle_items_and_bundled_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items?include=bundle-items,bundled-items
+ ... {"data": {"type": "items","attributes": {"sku": "${bundle_product.product_1.concrete_sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][bundle-items][data] 1
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: bundle-items
+ And Response include should contain certain entity type: bundled-items
+ And Response include element has self link: bundle-items
+ And Response include element has self link: bundled-items
+ And Response body parameter should be: [included][0][type] bundled-items
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${bundle_product.product_2.concrete_sku}
+ And Response body parameter should be: [included][1][type] bundled-items
+ And Response body parameter should be:
+ ... [included][1][attributes][sku]
+ ... ${bundle_product.product_3.concrete_sku}
+ And Response body parameter should be: [included][2][type] bundled-items
+ And Response body parameter should be:
+ ... [included][2][attributes][sku]
+ ... ${bundle_product.product_4.concrete_sku}
+ And Response body parameter should be: [included][3][type] bundle-items
+ And Response body parameter should be:
+ ... [included][3][attributes][sku]
+ ... ${bundle_product.product_1.concrete_sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [included][3][attributes][groupKey]
+ ... ${bundle_product.product_1.concrete_sku}
+ And Response body parameter should be:
+ ... [included][3][attributes][abstractSku]
+ ... ${bundle_product.product_1.abstract_sku}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_random_weight_product_to_cart_with_included_sales_units_and_measurenet_units
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a GET request: /concrete-products/${concrete.random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ When I send a POST request:
+ ... /carts/${cart_uid}/items?include=items,sales-units,product-measurement-units
+ ... {"data": {"type": "items","attributes": {"sku": "${concrete.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 2.5}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: sales-units
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include element has self link: items
+ And Response include element has self link: sales-units
+ And Response include element has self link: product-measurement-units
+ And Response body parameter should be: [included][0][type] product-measurement-units
+ And Response body parameter should be in: [included][0][id] ${packaging_unit.m} ${packaging_unit.cm}
+ And Response body parameter should be: [included][1][type] sales-units
+ And Response body parameter should be: [included][1][id] ${sales_unit_id}
+ And Response body parameter should be: [included][2][attributes][salesUnit][id] ${sales_unit_id}
+ And Response body parameter should be: [included][2][attributes][salesUnit][amount] 2.5
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_product_with_options_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items?include=items
+ ... {"data":{"type": "items","attributes":{"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1,"productOptions": [{ "sku": "${product_options.option_1}"},{ "sku": "${product_options.option_2}"}] }}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: items
+ And Response include element has self link: items
+ And Response body parameter should contain:
+ ... [included][0][id]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should contain:
+ ... [included][0][attributes][groupKey]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ ... 1
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ ... 1
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 2
+ Each array element of array in response should contain property:
+ ... [included][0][attributes][selectedProductOptions]
+ ... optionGroupName
+ Each array element of array in response should contain property:
+ ... [included][0][attributes][selectedProductOptions]
+ ... sku
+ Each array element of array in response should contain property:
+ ... [included][0][attributes][selectedProductOptions]
+ ... optionName
+ Each array element of array in response should contain property:
+ ... [included][0][attributes][selectedProductOptions]
+ ... price
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_with_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "${discount.product_1.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount.product_1.total_sum_of_discounts}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.discount_1.name}
+ And Response body parameter should be:
+ ... [data][attributes][discounts][0][amount]
+ ... ${discount.product_1.with_discount_20_percent_off_storage}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be:
+ ... [data][attributes][discounts][1][displayName]
+ ... ${discounts.discount_2.name}
+ And Response body parameter should be:
+ ... [data][attributes][discounts][1][amount]
+ ... ${discount.product_1.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_without_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request:
+ ... /carts/${cart_uid}/items
+ ... {"data": {"type": "items","attributes": {"sku": "${discount.product_3.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 1
+ And Response body parameter should be:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.discount_2.name}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][discounts][0][amount]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### PATCH #######
+
+Change_item_qty_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/${item_uid}?include=items
+ ... {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][sumPriceToPayAggregation]
+ ... ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Change_item_amount_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a GET request: /concrete-products/${concrete.random_weight.sku1}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.random_weight.sku1}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 1.5}}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request:
+ ... /carts/${cart_uid}/items/${item_uid}?include=items
+ ... {"data":{"type": "items","attributes":{"quantity": 2,"salesUnit": {"id": "${sales_unit_id}","amount": 3}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] 3.0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][sumPriceToPayAggregation]
+ ... ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+
+Delete_item_form_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_uid}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_uid}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_a_configurable_product_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "move-from-shopping-list-${random}"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response status code should be: 200
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response reason should be: No Content
+
+Change_configuration_and_quantity_in_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "update-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 61203
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "delete-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
+
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/negative.robot
new file mode 100644
index 0000000..f2ee4ed
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/negative.robot
@@ -0,0 +1,410 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart shared-carts customer-access spryker-core
+
+
+*** Test Cases ***
+Share_not_owned_shopping_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_non_existing_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_empty_permission_group_value_and_company_user_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"","idCartPermissionGroup":""}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCartPermissionGroup => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCompanyUser => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+
+Share_shopping_cart_without_company_user_attribute_and_cart_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCompanyUser => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_the_other_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_ottom_admin_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 2703
+ And Response reason should be: Forbidden
+ And Response should return error message: Cart can be shared only with company users from same company.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_without_access_token
+ When I send a POST request:
+ ... /carts/shoppingCartId/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Share_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a POST request:
+ ... /carts/shoppingCartId/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: ${401}
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Share_shopping_cart_with_empty_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts//shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: ${400}
+ And Response should return error code: 104
+ And Response reason should be: Bad Request
+ And Response should return error message: Cart uuid is missing.
+
+Share_shopping_cart_with_incorrect_cart_permission_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_non_existing_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"nonExistingCompanyUserId","idCartPermissionGroup":2}}}
+ Then Response status code should be: ${404}
+ And Response should return error code: 1404
+ And Response reason should be: Not Found
+ And Response should return error message: Company user not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_access_token
+ When I send a PATCH request:
+ ... /shared-carts/sharedCardId
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_permissions_of_shared_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a PATCH request:
+ ... /shared-carts/sharedCardId
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: ${401}
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_permissions_of_shared_shopping_cart_without_shared_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request:
+ ... /shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_permissions_of_shared_shopping_cart_with_incorrect_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request:
+ ... /shared-carts/${sharedCardId}
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_extra_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request:
+ ... /shared-carts/${sharedCardId}
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"test123456","idCartPermissionGroup":1}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_empty_permission_group_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request:
+ ... /shared-carts/${sharedCardId}
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":""}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts/${cartId}/items
+ ... {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request:
+ ... /carts/${cartId}/items/${concrete.available_product.with_stock.product_1.sku}
+ ... {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: ${403}
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_an_item_from_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}/items/${concrete.available_product.with_stock.product_1.sku}
+ Then Response status code should be: ${403}
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: ${403}
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_already_deleted_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: ${404}
+ And Response should return error code: 2705
+ And Response reason should be: Not Found
+ And Response should return error message: Shared cart not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/positive.robot
new file mode 100644
index 0000000..1cb383f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/cart_endpoints/shared_carts/positive.robot
@@ -0,0 +1,234 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue shared-carts product-relations customer-access spryker-core
+
+
+*** Test Cases ***
+Create_a_shared_shopping_cart_with_read_only_permissions_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ And I send a GET request: /carts/${cartId}?include=shared-carts
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][type] shared-carts
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][id] ${sharedCartId}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] shared-carts
+ And Response body parameter should be: [included][0][id] ${sharedCartId}
+ And Response body parameter should be: [included][0][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [included][0][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ And I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ And Response status code should be: 200
+ And Response body parameter should be:
+ ... [data][relationships][cart-permission-groups][data][0][type]
+ ... cart-permission-groups
+ And Response body parameter should be: [data][relationships][cart-permission-groups][data][0][id] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 1
+ And Response body parameter should be: [included][0][attributes][isDefault] True
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shared_shopping_cart_with_full_access_permissions
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request:
+ ... /carts/${cartId}/shared-carts
+ ... {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 2
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] FULL_ACCESS
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_by_Cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a PATCH request:
+ ... /shared-carts/${sharedCartId}
+ ... {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property:
+ ... [data][relationships][cart-permission-groups][data]
+ ... type
+ And Each array element of array in response should contain property:
+ ... [data][relationships][cart-permission-groups][data]
+ ... id
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts/${cartId}/items?include=items
+ ... {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ Then Save value to a variable: [included][0][id] concrete.available_product.with_stock.product_1.id
+ And Response status code should be: 201
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be:
+ ... [included][0][id]
+ ... ${concrete.available_product.with_stock.product_1.id}
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][sumPriceToPayAggregation]
+ ... 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Save value to a variable: [included][0][id] itemId
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] itemTotalPrice
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request:
+ ... /carts/${cartId}/items/${itemId}?include=items
+ ... {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${itemId}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][calculations][sumPriceToPayAggregation]
+ ... ${itemTotalPrice}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_an_item_from_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts/${cartId}?include=items
+ ... AND Save value to a variable: [data][relationships][items][data][0][id] itemId
+ When I send a DELETE request: /carts/${cartId}/items/${itemId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cartId}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":2}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_by_cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a DELETE request: /shared-carts/${sharedCartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/negative.robot
new file mode 100644
index 0000000..455c2b4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue merchant-category category-management
+
+
+*** Test Cases ***
+# endpoint receive category_node_id as int
+# here I use str type of the id and test response body
+
+Get_category_node_by_invalid_id
+ When I send a GET request: /category-nodes/test
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
+
+# non exists mean that type of id is valid but it does not exists at DB level
+
+Get_category_node_by_non_exist_id
+ When I send a GET request: /category-nodes/111111
+ Then Response status code should be: 404
+ And Response should return error code: 703
+ And Response should return error message: "Cant find category node with the given id."
+
+# Missing category_node_id have response error
+
+Get_absent_category_node
+ When I send a GET request: /category-nodes
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/positive.robot
new file mode 100644
index 0000000..70d96c1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_nodes/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue merchant-category category-management
+
+
+*** Test Cases ***
+Get_category_node_is_root_by_id
+ [Documentation] Step skip due to isse https://spryker.atlassian.net/browse/CC-25961
+ When I send a GET request: /category-nodes/${category_node.root_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.root_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ # And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][parents] 0
+ And Response should contain the array larger than a certain size: [data][attributes][children] 1
+ And Response body has correct self link internal
+
+Get_category_node_has_children_by_id
+ When I send a GET request: /category-nodes/${category_node.has_children_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.has_children_id}
+ And Response body parameter should be: [data][attributes][nodeId] ${category_node.has_children_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] nodeId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] name
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] order
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] children
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] parents
+ And Response body has correct self link internal
+
+Get_category_node_is_leaf_by_id
+ When I send a GET request: /category-nodes/${category_node.has_only_parent_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.has_only_parent_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][children] 0
+ And Response should contain the array larger than a certain size: [data][attributes][parents] 0
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_trees/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_trees/positive.robot
new file mode 100644
index 0000000..285c37e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/category_endpoints/category_trees/positive.robot
@@ -0,0 +1,58 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue merchant-category category-management
+
+
+*** Test Cases ***
+#GET requests
+
+Get_category_trees
+ When I send a GET request: /category-trees
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type category-trees
+ And Each array element of array in response should contain property with value: [data] id ${None}
+ And Response body parameter should be: [data][0][type] category-trees
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... nodeId
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... order
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... name
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... url
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... children
+ And Response body parameter should be:
+ ... [data][0][attributes][categoryNodesStorage][1][name]
+ ... ${category_node.storage_name}
+ And Response body parameter should be:
+ ... [data][0][attributes][categoryNodesStorage][1][url]
+ ... ${category_node.storage_url}
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][categoryNodesStorage][1][children][0][nodeId]
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][categoryNodesStorage][1][children][0][order]
+ And Response body parameter should be in: [data][0][attributes][categoryNodesStorage][1][children][1][name] ${subcategory_node.storage_name} ${subcategory_node.storage_name_2}
+ And Response body parameter should be in: [data][0][attributes][categoryNodesStorage][1][children][1][url] ${subcategory_node.storage_url} ${subcategory_node.storage_url_2}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][categoryNodesStorage][1][children][0][children]
+ ... 0
+ And Response should contain the array of size in:
+ ... [data][0][attributes][categoryNodesStorage]
+ ... ${qty_of_categories_in_category_trees}
+ ... ${qty_of_categories_in_category_trees_ssp}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][categoryNodesStorage][1][children]
+ ... ${qty_of_subcategories_in_category_trees}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/negative.robot
new file mode 100644
index 0000000..2b95b55
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/negative.robot
@@ -0,0 +1,635 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart checkout shipment order-management configurable-bundle promotions-discounts gift-cards configurable-product spryker-core
+
+
+*** Test Cases ***
+#POST requests
+
+Create_order_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${401}
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${403}
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${400}
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_email_&_salutation
+ [Documentation] step skip according https://spryker.atlassian.net/browse/CC-16504?focusedCommentId=304801
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "fake_email","salutation": "Freulein","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+ # And Response should return error message: customer.salutation => Salutation is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCart => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.email => Email is invalid.
+
+Create_order_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.email => This field is missing.
+
+Create_order_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Billing address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a GET request: /carts/${cartId}/?include=items
+ ... AND Save value to a variable: [included][0][id] item_group_key
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shipments": [{"requestedDeliveryDate": "2021-09-29", "idShipmentMethod": 1, "items": ["${itemGroupKey}"], "shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false}}],"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+#Bug CC-16999
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_payment_method_name"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Checkout payment is not valid
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentProviderName => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Shipment method not found.
+ And Response should return error code: 1102
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": []}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1104
+ And Response should return error message: Cart is empty.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_lower_order_total_price_than_threshold_limit
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.random_weight.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.random_weight.sku}", "${abstract.with_options.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message:
+ ... "You should add items for €40.00 to pass a recommended threshold. You cant proceed with checkout"
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_regular_shipment_&_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipment": {"idShipmentMethod": 0},"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${concrete.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4301
+ And Response should return error message:
+ ... Single and multiple shipments attributes are not allowed in the same request.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_invalid_delivery_date
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "None"},{"items": ["${concrete.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": "None"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shipments.0.requestedDeliveryDate => This value is not a valid date.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shipments.1.requestedDeliveryDate => This value is not a valid date.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_invalid_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND I send a GET request: /carts/${cartId}/?include=items
+ ... AND Save value to a variable: [included][0][id] item_group_key
+ ... AND Save value to a variable: [included][1][id] item_with_option_group_key
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${itemGroupKey}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${itemWithOptionGroupKey}"],"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_empty_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete.with_options.sku}"],"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4302
+ And Response should return error message:
+ ... Provided address is not valid. You can either provide address ID or address fields.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_without_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete.with_options.sku}"],"shippingAddress": {},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: shipments.1.shippingAddress => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/positive.robot
new file mode 100644
index 0000000..cf0c965
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout/positive.robot
@@ -0,0 +1,873 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core cart checkout shipment order-management configurable-bundle promotions-discounts gift-cards configurable-product payments inventory-management default-run-feature
+
+
+*** Test Cases ***
+#POST requests
+
+Create_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_include_orders
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ #totals
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][salutation]
+ ... ${yves_user.salutation}
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][firstName]
+ ... ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][lastName]
+ ... ${yves_user.last_name}
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][address1]
+ ... ${default.address1}
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][address2]
+ ... ${default.address2}
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][address3]
+ ... ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be:
+ ... [included][0][attributes][billingAddress][iso2Code]
+ ... ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][salutation]
+ ... ${yves_user.salutation}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][firstName]
+ ... ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][lastName]
+ ... ${yves_user.last_name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address1]
+ ... ${default.address1}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address2]
+ ... ${default.address2}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address3]
+ ... ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][iso2Code]
+ ... ${default.iso2Code}
+ #items
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][unitTaxAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][sumTaxAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][sumSubtotalAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][unitSubtotalAggregation]
+ ... 0
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][unitProductOptionPriceAggregation]
+ ... 0
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sumProductOptionPriceAggregation]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][unitDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][sumDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][unitDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][sumDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][unitPriceToPayAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][sumPriceToPayAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][taxRateAverageAggregation]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][0][metadata][superAttributes]
+ ... 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][sumAmount]
+ ... 0
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode]
+ ... None
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][quantity]
+ ... 1
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][0][productOptions]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be:
+ ... [included][0][attributes][expenses][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be:
+ ... [included][0][attributes][expenses][0][unitDiscountAmountAggregation]
+ ... None
+ And Response body parameter should be:
+ ... [included][0][attributes][expenses][0][sumDiscountAmountAggregation]
+ ... None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][expenses][0][taxAmountAfterCancellation]
+ ... None
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][payments][0][paymentProvider]
+ ... ${payment_provider_name}
+ And Response body case-insensitive parameter should be:
+ ... [included][0][attributes][payments][0][paymentMethod]
+ ... ${payment_method_name}
+ #shipments
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][shipments][0][defaultGrossPrice]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.product_1.concrete_sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${bundle_product.product_1.concrete_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_with_mode.net_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 20}}}
+ When I send a POST request:
+ ... /checkout
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 5},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_with_weight_product_&_product_options
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a GET request: /concrete-products/${concrete.random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1, "productOptions": [{"sku": "${product_options.option_1}"}]}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}", "${concrete.with_options.sku}", "${concrete.random_weight.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ #product_1
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][0][productOptions]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ #product_2
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][name]
+ ... ${concrete.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][productOptions][0][optionGroupName]
+ ... Warranty
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][productOptions][0][sku]
+ ... ${product_options.option_1}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][productOptions][0][optionName]
+ ... ${product_options.option_1_name}
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][items][1][productOptions][0][price]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ #product_3
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][name]
+ ... ${concrete.random_weight.name}
+ And Response body parameter should be: [included][0][attributes][items][2][sku] ${concrete.random_weight.sku}
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][2][productOptions]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][items][2][quantity] 1
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][2][salesUnit][productMeasurementUnit][name]
+ ... ${packaging_unit.m_name} ${packaging_unit.m_name2}
+ And Response body parameter should be in: [included][0][attributes][items][2][salesUnit][productMeasurementUnit][code] ${packaging_unit.m} ${packaging_unit.cm}
+ And Response body has correct self link internal
+
+Create_order_with_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete.available_product.with_stock_and_never_out_of_stock.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] concrete.with_options.id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete.with_options.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][name]
+ ... ${concrete.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [included][0][attributes][shipments] 0
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 2
+
+Create_order_with_split_shipments_&_same_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete.available_product.with_stock_and_never_out_of_stock.id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] concrete.with_options.id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete.with_options.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][name]
+ ... ${concrete.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][shipments][0][defaultGrossPrice]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][currencyIsoCode]
+ ... ${currency.eur.code}
+
+Create_order_with_same_items_in_different_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete.available_product.with_stock_and_never_out_of_stock.id
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than:
+ ... [included][0][attributes][shipments][0][defaultGrossPrice]
+ ... 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 1
+
+Create_order_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 3}}}
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be:
+ ... [included][0][attributes][totals][expenseTotal]
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 30000
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter with rounding should be:
+ ... [included][0][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [included][0][attributes][items] 3
+ #shipments
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][defaultGrossPrice]
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][shipments][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][unitAmount]
+ ... None
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][sumAmount]
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][displayName]
+ ... ${discounts.discount_3.name}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][description]
+ ... ${discounts.discount_3.description}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][voucherCode]
+ ... None
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["Free standard delivery"][quantity]
+ ... 1
+
+Create_order_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_1.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_2.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_3.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${discount.product_1.sku}", "${discount.product_2.sku}", "${discount.product_3.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body has correct self link internal
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount.product_1.total_sum_of_discounts}
+ ... +
+ ... ${discount.product_2.total_sum_of_discounts}
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount_total_sum}
+ ... +
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [included][0][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [included][0][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #item 1 - "20% off storage" discount and "10% off minimum order" discount
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][0][calculatedDiscounts]
+ ... 2
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${discount.product_1.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${discount.product_1.sku}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount]
+ ... ${discount.product_1.with_discount_20_percent_off_storage} ${discount.product_1.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][sumAmount]
+ ... ${discount.product_1.with_discount_20_percent_off_storage} ${discount.product_1.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][displayName]
+ ... ${discounts.discount_1.name} ${discounts.discount_2.name}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][description]
+ ... ${discounts.discount_1.description} ${discounts.discount_2.description}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode]
+ ... None
+ And Response body parameter should be:
+ ... [included][0][attributes][items][0][calculatedDiscounts][0][quantity]
+ ... 1
+ #item 2 - "20% off storage" discount and "10% off minimum order" discount
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][1][calculatedDiscounts]
+ ... 2
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${discount.product_2.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${discount.product_2.sku}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][unitAmount]
+ ... ${discount.product_2.with_discount_20_percent_off_storage} ${discount.product_2.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][sumAmount]
+ ... ${discount.product_2.with_discount_20_percent_off_storage} ${discount.product_2.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][displayName]
+ ... ${discounts.discount_1.name} ${discounts.discount_2.name}
+ And Response body parameter should be in:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][description]
+ ... ${discounts.discount_1.description} ${discounts.discount_2.description}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][voucherCode]
+ ... None
+ And Response body parameter should be:
+ ... [included][0][attributes][items][1][calculatedDiscounts][0][quantity]
+ ... 1
+ #item 3 - "10% off minimum order" discount
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][items][2][calculatedDiscounts]
+ ... 1
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][unitAmount]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][sumAmount]
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][displayName]
+ ... ${discounts.discount_2.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][description]
+ ... ${discounts.discount_2.description}
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][voucherCode]
+ ... None
+ And Response body parameter should be:
+ ... [included][0][attributes][items][2][calculatedDiscounts][0][quantity]
+ ... 1
+ #calculatedDiscounts - "20% off storage" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... sumAmount: ${discounts.discount_1.total_sum_for_products_1_and_2}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... displayName: ${discounts.discount_1.name}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... description: ${discounts.discount_1.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 3
+ #calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... sumAmount: ${discounts.discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... displayName: ${discounts.discount_2.name}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]
+ ... description: ${discounts.discount_2.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 3
+
+Create_order_with_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_product.sku}"]}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_product.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_product.sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesOrderItemConfiguration][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment_method.name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ # payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment_provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment_method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment_method.name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment_method.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
diff --git a/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/negative.robot
new file mode 100644
index 0000000..899a1a6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/negative.robot
@@ -0,0 +1,414 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart checkout payments shipment spryker-core
+
+
+*** Test Cases ***
+#POST requests
+Provide_checkout_data_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Provide_checkout_data_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Provide_checkout_data_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Provide_checkout_data_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Provide_checkout_data_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Provide_checkout_data_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "fake_email","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+
+Provide_checkout_data_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... idCart => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.email => Email is invalid.
+
+Provide_checkout_data_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... customer.email => This field is missing.
+
+Provide_checkout_data_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.iso2Code => This value should not be blank.
+
+Provide_checkout_data_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.city => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... billingAddress.iso2Code => This field is missing.
+
+Provide_checkout_data_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.iso2Code => This value should not be blank.
+
+Provide_checkout_data_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.city => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... shippingAddress.iso2Code => This field is missing.
+
+Provide_checkout_data_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+
+Provide_checkout_data_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... payments.0.paymentProviderName => This field is missing.
+
+Provide_checkout_data_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
diff --git a/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/positive.robot
new file mode 100644
index 0000000..635899e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/checkout_endpoints/checkout_data/positive.robot
@@ -0,0 +1,246 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart checkout payments shipment spryker-core
+
+
+*** Test Cases ***
+#POST requests
+
+Provide_checkout_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_with_only_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data", "attributes": {"idCart": "${cart_id}","payments": []}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_method_name"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.product_1.concrete_sku}","quantity": 1}}}
+ When I send a POST request:
+ ... /checkout-data
+ ... {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][carrierName]
+ ... ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][selectedShipmentMethods][0][currencyIsoCode]
+ ... ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/negative.robot
new file mode 100644
index 0000000..e4242f5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_company_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/3525626
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
+
+Request_company_without_access_token
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_company_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/positive.robot
new file mode 100644
index 0000000..136a5aa
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/companies/positive.robot
@@ -0,0 +1,39 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_company_by_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] companies
+ And Response body parameter should be: [data][id] ${company_id}
+ And Response body parameter should be: [data][attributes][name] ${company_name}
+ And Response body parameter should be: [data][attributes][status] approved
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][attributes] 3
+
+Request_company_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] companies
+ And Response body parameter should be: [data][0][attributes][name] ${company_name}
+ And Response body parameter should be: [data][0][attributes][status] approved
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][0][attributes] 3
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/negative.robot
new file mode 100644
index 0000000..c77a1c4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_business_unit_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/45768
+ Then Response status code should be: 404
+ And Response should return error code: 1901
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit not found.
+
+Request_business_unit_without_access_token
+ When I send a GET request: /company-business-units/456789
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_business_unit_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_business_unit_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 404
+ And Response should return error code: 1901
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/positive.robot
new file mode 100644
index 0000000..c89d8bd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit/positive.robot
@@ -0,0 +1,74 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_business_unit_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] ${business_unit_name}
+ And Response should contain the array of a certain size: [data][attributes] 7
+ And Response body parameter should be: [data][attributes][defaultBillingAddress] None
+ And Response body parameter should not be EMPTY: [data][attributes][email]
+ And Response body parameter should not be EMPTY: [data][attributes][phone]
+ And Response body parameter should contain: [data][attributes] externalUrl
+ And Response body parameter should contain: [data][attributes] bic
+ And Response body parameter should contain: [data][attributes] iban
+
+Request_business_unit_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][name] ${business_unit_name}
+ And Response should contain the array of a certain size: [data][0][attributes] 7
+
+Request_business_unit_by_id_with_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request:
+ ... /company-business-units/${business_unit_id}?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should contain: [data][relationships] companies
+ And Response body parameter should contain: [data][relationships] company-business-unit-addresses
+
+Request_business_unit_by_mine_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... company-business-units
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array of a certain size: [data][0][relationships] 2
+ Response body parameter should contain: [data][0][relationships] companies
+ Response body parameter should contain: [data][0][relationships] company-business-unit-addresses
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot
new file mode 100644
index 0000000..44b6135
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_business_unit_address_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/3456r7t8y8u
+ Then Response status code should be: 404
+ And Response should return error code: 2001
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit address not found.
+
+Request_business_unit_address_without_access_token
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_business_unit_address_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_business_unit_address_with_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/mine
+ Then Response status code should be: 404
+ And Response should return error code: 2001
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit address not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot
new file mode 100644
index 0000000..d892a72
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_business_units_address_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-unit-addresses
+ And Response body parameter should be: [data][id] ${busines_unit_address_id}
+ And Response should contain the array of a certain size: [data][attributes] 8
+ And Response body parameter should not be EMPTY: [data][attributes][address1]
+ And Response body parameter should not be EMPTY: [data][attributes][address2]
+ And Response body parameter should not be EMPTY: [data][attributes][zipCode]
+ And Response body parameter should not be EMPTY: [data][attributes][city]
+ And Response body parameter should not be EMPTY: [data][attributes][iso2Code]
+ And Response body parameter should not be EMPTY: [data][attributes][comment]
+ And Response body parameter should contain: [data][attributes] address3
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/negative.robot
new file mode 100644
index 0000000..72d0c8f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_company_role_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/6334few7
+ Then Response status code should be: 404
+ And Response should return error code: 2101
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company role not found.
+
+Request_company_role_without_access_token
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_role_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_company_role_if_role_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 404
+ And Response should return error code: 2101
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company role not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/positive.robot
new file mode 100644
index 0000000..bba8f17
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_roles/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_company_role_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-roles
+ And Response body parameter should be in: [data][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+
+Request_company_role_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of size in: [data] 2 3
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Response body parameter should be in: [data][1][attributes][name] Admin Buyer
+ And Response body parameter should be in: [data][0][attributes][name] Admin Buyer
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be in: [data][1][attributes][isDefault] True False
+
+Request_company_role_by_mine_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response body parameter should contain: [data][0][relationships][companies][data][0][type] companies
+
+Request_company_role_by_id_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][relationships][companies][data][0][id]
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/negative.robot
new file mode 100644
index 0000000..e47d4c1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/negative.robot
@@ -0,0 +1,85 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+
+*** Test Cases ***
+Request_access_token_by_invalid_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This is not a valid UUID.
+
+Request_access_token_by_empty_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This value should not be blank.
+
+Request_access_token_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_using_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=546789
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Request_access_token_with_missing_token
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_access_token_if_user_belong_to_other_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 003
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Failed to authenticate user.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/positive.robot
new file mode 100644
index 0000000..07f5685
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_user_access_tokens/positive.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+
+*** Test Cases ***
+Get_access_token_for_company_user_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ When I send a POST request:
+ ... /company-user-access-tokens
+ ... {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-user-access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/negative.robot
new file mode 100644
index 0000000..6e2ac3f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/negative.robot
@@ -0,0 +1,40 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+
+*** Test Cases ***
+Request_company_user_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-users/645647
+ Then Response status code should be: 404
+ And Response should return error code: 1404
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company user not found
+
+Request_company_user_without_access_token
+ When I send a GET request: /company-users/
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_user_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-users/
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Retrieve_list_of_company_users_by_user_without_admin_role
+ When I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
diff --git a/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/positive.robot
new file mode 100644
index 0000000..4404010
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/company_endpoints/company_users/positive.robot
@@ -0,0 +1,96 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+
+*** Test Cases ***
+Request_company_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-users
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 12
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response should contain the array of a certain size: [data][0][attributes] 2
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][isDefault] False
+ And Response body has correct self link
+
+Request_company_users_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-users/mine
+ ... AND Save value to a variable: [data][id] company_user_id
+ When I send a GET request: /company-users/${company_user_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] company-users
+
+Request_company_users_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] company-users
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][isDefault] False
+
+Request_company_users_include_customers_and_roles_and_business_units
+ [Documentation] last step need to be fixed, flakery cause one of the array relationship is not contain company-role
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-users?include=customers,company-business-units,company-roles
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array larger than a certain size: [data][0][relationships] 1
+ And Response should contain the array smaller than a certain size: [data][0][relationships] 4
+ And Response body parameter should contain: [data][0][relationships] company-business-units
+ And Response body parameter should contain: [data][0][relationships] customers
+ And Nested array element should contain sub-array at least once: [data] [relationships] company-roles
+
+Request_companies_users_if_user_has_4_companies
+ [Setup] Run Keywords I get access token for the customer: ${user_with_multiple_companies}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I add 'admin' role to company user and get company_user_uuid: ${user_with_multiple_companies} BoB-Hotel-Jim business-unit-jim-1
+ ... AND I get access token for the company user by uuid: ${company_user_uuid}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 4
+ And Each array element of array in response should contain property with value: [data] type company-users
+
+Request_companies_users_with_include_customers_and_filtered_by_company_role
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company-role-uuid
+ When I send a GET request: /company-users?include=customers&filter[company-roles.id]=${company-role-uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array of a certain size: [data][0][relationships] 1
+ And Response body parameter should contain: [data][0][relationships] customers
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
new file mode 100644
index 0000000..1eec69e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product alternative-products
+
+
+*** Test Cases ***
+Get_abstract_product_alternative_for_concrete_product_with_invalid_sku_of_product
+ When I send a GET request: /concrete-products/65789/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response body parameter should be: [errors][0][detail] Concrete product is not found.
+
+Get_abstract_product_alternative_for_concrete_product_using_abstract_product_SKU
+ When I send a GET request:
+ ... /concrete-products/${bundle_product.product_2.abstract_sku}/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response body parameter should be: [errors][0][detail] Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
new file mode 100644
index 0000000..4055d83
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
@@ -0,0 +1,63 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product discontinued-products alternative-products
+
+
+*** Test Cases ***
+Get_concrete_alternative_product_for_a_product_that_has_none
+ When I send a GET request:
+ ... /concrete-products/${bundle_product.product_2.concrete_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response reason should be: OK
+
+Get_concrete_alternative_product
+ When I send a GET request:
+ ... /concrete-products/${concrete.alternative_products.product_1.sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response body should contain: id
+ And Response body parameter should contain: [data][0][attributes] sku
+ And Response body parameter should contain: [data][0][attributes] isDiscontinued
+ And Response body parameter should contain: [data][0][attributes] discontinuedNote
+ And Response body parameter should contain: [data][0][attributes] averageRating
+ And Response body parameter should contain: [data][0][attributes] reviewCount
+ And Response body parameter should contain: [data][0][attributes] productAbstractSku
+ And Response body parameter should contain: [data][0][attributes] name
+ And Response body parameter should contain: [data][0][attributes] description
+ And Response body parameter should contain: [data][0][attributes] attributes
+ And Response body parameter should contain: [data][0][attributes] superAttributesDefinition
+ And Response body parameter should contain: [data][0][attributes] metaTitle
+ And Response body parameter should contain: [data][0][attributes] metaKeywords
+ And Response body parameter should contain: [data][0][attributes] metaDescription
+ And Response body parameter should contain: [data][0][attributes] attributeNames
+ And Response should contain the array of a certain size: [data][0][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][0][attributes][attributeNames] 7
+ And Response body has correct self link
+
+Get_concrete_alternative_product_with_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /concrete-products/${concrete.alternative_products.product_1.sku}/concrete-alternative-products?include=concrete-product-image-sets,concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+ And Response include element has self link: concrete-product-prices
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
new file mode 100644
index 0000000..8a018d1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
@@ -0,0 +1,38 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product inventory-management
+
+
+*** Test Cases ***
+Request_concrete_availability_by_abstract_SKU
+ When I send a GET request:
+ ... /concrete-products/${abstract.alternative_products.product_1.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
new file mode 100644
index 0000000..dd805da
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product inventory-management
+
+
+*** Test Cases ***
+Request_concrete_availability_by_concrete_SKU_with_stock
+ When I send a GET request:
+ ... /concrete-products/${concrete.available_product.with_stock.product_2.sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete.available_product.with_stock.product_2.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_with_stock_and_never_out_of_stock
+ When I send a GET request:
+ ... /concrete-products/${concrete.available_product.with_stock_and_never_out_of_stock.sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] True
+ And Response body parameter should not be EMPTY: [data][0][attributes][quantity]
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_without_stock
+ When I send a GET request:
+ ... /concrete-products/${concrete.available_product.without_stock.sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete.available_product.without_stock.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
new file mode 100644
index 0000000..15c99c4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
@@ -0,0 +1,38 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Request_product_image_with_abstract_SKU
+ When I send a GET request:
+ ... /concrete-products/${bundle_product.product_2.abstract_sku}/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
+
+Request_product_image_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
new file mode 100644
index 0000000..2347767
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
@@ -0,0 +1,40 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Request_concrete_product_with_one_image_set
+ When I send a GET request: /concrete-products/${concrete.one_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete.one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+
+Request_concrete_product_with_5_image_sets
+ When I send a GET request: /concrete-products/${concrete.multiple_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete.multiple_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 5
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
new file mode 100644
index 0000000..b8d2083
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product prices
+
+
+*** Test Cases ***
+Request_product_prices_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/${bundle_product.product_2.abstract_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Request_product_prices_with_empty_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products//concrete-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_prices_with_special_characters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_prices_by_concrete_sku_product_doesn't_exist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/4567890/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Request_product_prices_without_access_token
+ When I send a GET request: /concrete-products/${concrete.one_image_set.sku}/concrete-product-prices
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_product_prices_without_wrong_access_token
+ [Setup] I set Headers: Authorization=8ur30jfpwoe
+ When I send a GET request: /concrete-products/${concrete.one_image_set.sku}/concrete-product-prices
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
new file mode 100644
index 0000000..90a58c6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product prices
+
+
+*** Test Cases ***
+Request_concrete_product_with_only_default_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete.one_image_set.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete.one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should contain:
+ ... [data][0][attributes][prices][0][currency][code]
+ ... ${currency.eur.code}
+ And Response body parameter should contain:
+ ... [data][0][attributes][prices][0][currency][name]
+ ... ${currency.eur.name}
+ And Response body parameter should contain:
+ ... [data][0][attributes][prices][0][currency][symbol]
+ ... ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+
+Request_concrete_product_with_default_and_original_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete.with_original_prices.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete.with_original_prices.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices][0][grossAmount]
+ And Each array element of array in response should contain property with value:
+ ... [data][0][attributes][prices]
+ ... netAmount
+ ... ${None}
+ And Each array element of array in response should contain property with value:
+ ... [data][0][attributes][prices]
+ ... volumePrices
+ ... ${array}
+
+Request_concrete_product_with_volume_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete.volume_prices_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete.volume_prices_sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... grossAmount
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... netAmount
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][prices][0][volumePrices]
+ ... quantity
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/negative.robot
new file mode 100644
index 0000000..18e40c9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/negative.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Request_product_concrete_with_product_doesn't_exist
+ When I send a GET request: /concrete-products/354656u7i8
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.product_2.abstract_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_empty_SKU
+ When I send a GET request: /concrete-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_concrete_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/positive.robot
new file mode 100644
index 0000000..b89965d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/concrete_products_endpoints/concrete_products/positive.robot
@@ -0,0 +1,77 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Request_product_concrete_by_id
+ When I send a GET request: /concrete-products/${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete.alternative_products.product_1.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete.alternative_products.product_1.sku}
+ And Response body parameter should be:
+ ... [data][attributes][name]
+ ... ${concrete.alternative_products.product_1.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+
+Request_product_concrete_with_included_image_sets
+ When I send a GET request: /concrete-products/${concrete.one_image_set.sku}?include=concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete.one_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete.one_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 5
+ And Response should contain the array of a certain size: [data][attributes][attributes] 5
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+
+Request_product_concrete_with_included_availabilities_and_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /concrete-products/${concrete.with_original_prices.sku}?include=concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete.with_original_prices.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete.with_original_prices.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-availabilities
+
+Request_product_concrete_with_included_abstract_product
+ When I send a GET request: /concrete-products/${concrete.multiple_image_set.sku}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete.multiple_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete.multiple_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
new file mode 100644
index 0000000..88d21b4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
@@ -0,0 +1,216 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product configurable-bundle
+
+
+*** Test Cases ***
+####### GET #######
+
+Get_configurable_bundle_templates_by_invalid_configurable_bundle.template_id
+ When I send a GET request: /configurable-bundle-templates/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3901
+ And Response should return error message: Configurable bundle template not found.
+
+####### POST ######
+
+Add_configured_bundle_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a POST request:
+ ... /carts/${cart_id}/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "fake","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "fake" not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Add_configured_bundle_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request:
+ ... /carts/fake/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Add_configured_bundle_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /carts//configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_configured_bundle_item_to_cart_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization="fake"
+ When I send a POST request:
+ ... /carts/fake/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_configured_bundle_item_to_cart_with_missing_token
+ When I send a POST request:
+ ... /carts/fake/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_configured_bundle_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a POST request:
+ ... /carts/${cart_id}/configured-bundles
+ ... {"data": {"type": "config","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Add_configured_bundle_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /carts/${cart_id}/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Add_configured_bundle_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request:
+ ... /carts/${cart_id}/configured-bundles
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": "","templateUuid": "","items": [{"sku": "","quantity": 2,"slotUuid": ""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+####### PATCH #######
+
+Update_configured_bundle_item_in_cart_with_non_existing_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a PATCH request:
+ ... /carts/${cart_id}/configured-bundles/fake
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_configured_bundle_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a PATCH request:
+ ... /carts/${cart_id}/configured-bundles/
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_configured_bundle_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request:
+ ... /carts/fake/configured-bundles/fake
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Update_configured_bundle_item_in_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request:
+ ... /carts//configured-bundles/fake
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+####### DELETE #######
+
+Delete_configured_bundle_item_from_the_cart_with_wrong_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+
+Delete_configured_bundle_item_from_the_cart_with_empty_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_item_from_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake/configured-bundles/fake
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Delete_configured_bundle_item_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts//configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
new file mode 100644
index 0000000..6e3b0b8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
@@ -0,0 +1,267 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product configurable-bundle
+
+
+*** Test Cases ***
+Get_configurable_bundle_templates
+ When I send a GET request: /configurable-bundle-templates
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_slots
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-slots
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... relationships
+ ... configurable-bundle-template-slots
+ And Each array element of array in response should contain property with value:
+ ... [included]
+ ... type
+ ... configurable-bundle-template-slots
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_image_sets
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... relationships
+ ... configurable-bundle-template-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes images
+ And Each array element of array in response should contain nested property:
+ ... [included]
+ ... [attributes][images]
+ ... externalUrlLarge
+ And Each array element of array in response should contain nested property:
+ ... [included]
+ ... [attributes][images]
+ ... externalUrlSmall
+ And Each array element of array in response should contain property with value:
+ ... [included]
+ ... type
+ ... configurable-bundle-template-image-sets
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_by_configurable_bundle.template_id
+ When I send a GET request:
+ ... /configurable-bundle-templates/${configurable_bundle.template_id}?include=configurable-bundle-template-slots,configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should be: [data][id] ${configurable_bundle.template_id}
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle.template_name}
+ Response should contain the array of a certain size:
+ ... [data][relationships][configurable-bundle-template-slots][data]
+ ... 4
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][configurable-bundle-template-slots][data]
+ ... type
+ ... configurable-bundle-template-slots
+ And Each array element of array in response should contain property:
+ ... [data][relationships][configurable-bundle-template-slots][data]
+ ... id
+ Response should contain the array of a certain size:
+ ... [data][relationships][configurable-bundle-template-image-sets][data]
+ ... 1
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][configurable-bundle-template-image-sets][data]
+ ... type
+ ... configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property:
+ ... [data][relationships][configurable-bundle-template-slots][data]
+ ... id
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Response body parameter should be: [included][0][type] configurable-bundle-template-slots
+ And Response body parameter should be: [included][1][type] configurable-bundle-template-slots
+ And Response body parameter should be: [included][2][type] configurable-bundle-template-slots
+ And Response body parameter should be: [included][3][type] configurable-bundle-template-slots
+ And Response body parameter should be: [included][4][type] configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property:
+ ... [included][4][attributes][images]
+ ... externalUrlLarge
+ And Each array element of array in response should contain property:
+ ... [included][4][attributes][images]
+ ... externalUrlSmall
+
+Get_configurable_bundle_templates_including_concrete_products_concrete_product_prices_concrete_product_image_sets
+ [Documentation] https://spryker.atlassian.net/browse/CC-16634
+ [Tags] skip-due-to-issue
+ When I send a GET request:
+ ... /configurable-bundle-templates/${configurable_bundle.template_id}?include=configurable-bundle-template-slots,concrete-products,concrete-product-prices,concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should contain: [data] id
+ And Response body parameter should contain: [data] attributes
+ And Response body parameter should contain: [data] links
+ And Response should contain the array larger than a certain size:
+ ... [data][relationships][configurable-bundle-template-slots][data]
+ ... 0
+ # TODO check included concrete-products,configurable-bundle-template-slots,concrete-product-prices,concrete-product-image-sets after BUG CC-16634 fix
+ And Response should contain the array of a certain size: [included] 9
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ And Response body has correct self link
+
+Add_configured_bundle_item_to_the_cart_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a POST request:
+ ... /carts/${cart_id}/configured-bundles?include=items
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response should contain the array of a certain size: [data][relationships][items] 1
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][items][data]
+ ... type
+ ... items
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${configurable_bundle.first_slot_item_sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculations][sumPriceToPayAggregation]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_configurable_bundle.quantity_in_the cart_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a PATCH request:
+ ... /carts/${cart_id}/configured-bundles/${bundle_group_key}?include=items
+ ... {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${configurable_bundle.first_slot_item_sku}
+ And Response body parameter should be: [included][0][attributes][configuredBundle][quantity] 12
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Delete_configured_bundle_item_from_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configurable_bundle.quantity},"templateUuid": "${configurable_bundle.template_id}","items": [{"sku": "${configurable_bundle.first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle.first_slot_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/${bundle_group_key}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/negative.robot
new file mode 100644
index 0000000..805e9b2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/negative.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cms content-item
+
+
+*** Test Cases ***
+Get_cms_page_list_by_fake_id
+ When I send a GET request: /cms-pages/:cms
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
+Get_cms_page_list_by_wrond_id
+ When I send a GET request: /cms-pages/${abstract_list.id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/positive.robot
new file mode 100644
index 0000000..20a6923
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/cms_pages/positive.robot
@@ -0,0 +1,64 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/cms_steps.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_pages_list
+ When I send a GET request: /cms-pages
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_page.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body array element should contain property with value at least once: [data] [attributes][name] ${cms_page.name}
+ And Response body array element should contain property with value at least once: [data] [attributes][url] ${cms_page.url_en}
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... [attributes][isSearchable]
+ ... True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body has correct self link
+
+Get_specific_cms_page
+ [Setup] Run Keywords I send a GET request: /cms-pages
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] cms_page_id
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][isSearchable]
+ And Response body should contain: pageKey
+ And Response body should contain: validTo
+ And Response body has correct self link internal
+
+Get_specific_cms_with_includes
+ [Setup] Add content product abstract list to cms page in DB ${cms_page.product_lists_id}
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page.product_lists_id}?include=content-product-abstract-lists
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page.product_lists_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should be: [data][attributes][name] ${cms_page.product_lists_name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][content-product-abstract-lists][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: content-product-abstract-lists
+ And Response include element has self link: content-product-abstract-lists
+ [Teardown] Run Keyword Delete latest cms page version by uuid from DB ${cms_page.product_lists_id}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/negative.robot
new file mode 100644
index 0000000..5aa44ee
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/negative.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue content-item
+
+
+*** Test Cases ***
+Get_banner_without_id
+ When I send a GET request: /content-banners
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_banner_with_wrong_content_id_type
+ When I send a GET request: /content-banners/${abstract_list.id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 2203
+ And Response should return error message: Content type is invalid.
+
+Get_banner_with_invalid_content_id
+ When I send a GET request: /content-banners/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/positive.robot
new file mode 100644
index 0000000..0708731
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_banners/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue content-item
+
+
+*** Test Cases ***
+Get_banner
+ When I send a GET request: /content-banners/${banner.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${banner.id}
+ And Response body parameter should be: [data][type] content-banners
+ And Response body parameter should be: [data][attributes][title] ${banner.name}
+ And Response body parameter should not be EMPTY: [data][attributes][subtitle]
+ And Response body parameter should contain: [data][attributes][imageUrl] jpg
+ And Response body parameter should not be EMPTY: [data][attributes][clickUrl]
+ And Response body parameter should be: [data][attributes][altText] ${banner.name}
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot
new file mode 100644
index 0000000..0829c89
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot
@@ -0,0 +1,44 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product content-item
+
+
+*** Test Cases ***
+Get_abstract_product_list_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_products_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_with_no_id
+ When I send a GET request: /content-product-abstract-lists
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_missing_id
+ When I send a GET request: /content-product-abstract-lists//abstract-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_no_id
+ When I send a GET request: /content-product-abstract-lists/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot
new file mode 100644
index 0000000..822e069
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product content-item
+
+
+*** Test Cases ***
+Abstract_product_list
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+
+Abstract_product_list_abstract_products
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.id}/abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_list.size}
+ And Each array element of array in response should contain property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_list.product1_sku}
+ And Response body parameter should be: [data][0][attributes][name] ${abstract_list.product1_name}
+ And Response body parameter should be: [data][1][attributes][sku] ${abstract_list.product2_sku}
+ And Response body parameter should be: [data][1][attributes][name] ${abstract_list.product2_name}
+
+# Bug CC-16994
+# there is a bug in b2b - include does not work - CC-16634
+
+Abstract_product_list_with_include
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.id}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size:
+ ... [data][relationships][abstract-products][data]
+ ... ${abstract_list.size}
+ And Response should contain the array of a certain size: [included] ${abstract_list.size}
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/negative.robot
new file mode 100644
index 0000000..d1e3aff
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/negative.robot
@@ -0,0 +1,413 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core
+
+
+*** Test Cases ***
+######POST#####
+Create_customer_address_with_missing_required_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"address3": "${default.address3}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address1 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address2 => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail city => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... iso2Code => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... isDefaultShipping => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... isDefaultBilling => This field is missing.
+
+Create_customer_address_with_empty_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","country": "","iso2Code": "","company":"","phone": "","isDefaultShipping": "","isDefaultBilling": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... city => This value should not be blank.
+
+Create_customer_address_with_invalid_salutation
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "Fake","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+
+Create_customer_address_with_customer_reference_not_matching_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/${yves_second_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_non_existing_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/DE--10000/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers//addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_type
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+######GET#####
+
+Get_non-existent_customer_address
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Get_other_customer_address_list
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_address_list_for_non-existent_customer
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/fake/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Get_address_list_with_no_token
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Get_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_other_customer_address_by_id_and_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+######PATCH#####
+
+Patch_customer_address_without_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Patch_customer_address_with_fake_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses/fake
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Patch_another_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_another_customer_address_by_id_using_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request:
+ ... /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_no_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request:
+ ... /customers//addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_wrong_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request:
+ ... /customers/DE--1/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_empty_required_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"salutation": null,"firstName": null,"lastName": null, "address1": null,"address2": null,"zipCode": null,"city": null,"iso2Code": null}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address1 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... address2 => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... zipCode => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... city => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_invalid_salutation
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"salutation": "Fake"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+######DELETE#####
+
+Delete_customer_address_with_wrong_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Delete_customer_address_with_no_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/positive.robot
new file mode 100644
index 0000000..b552798
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/addresses/positive.robot
@@ -0,0 +1,262 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core
+
+
+*** Test Cases ***
+#####POST#####
+Create_customer_address_with_all_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ When I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_only_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] None
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] None
+ And Response body parameter should be: [data][attributes][phone] None
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_shipping_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": true,"isDefaultBilling": false}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_billing_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request:
+ ... /customers/${yves_user.reference}/addresses
+ ... {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": true}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+#GET
+
+Get_empty_list_of_customer_addresses
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ Response should contain the array of a certain size: [data] 0
+
+Get_list_of_customer_addresses_with_1_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] address_uid
+ And Response body parameter should be: [data][0][type] addresses
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][0][attributes][city] ${default.city}
+ And Response body parameter should be: [data][0][attributes][country] ${default.country}
+ And Response body parameter should be: [data][0][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][0][attributes][company] ${default.company}
+ And Response body parameter should be: [data][0][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][0][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][0][attributes][isDefaultBilling] True
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_list_of_customer_addresses_with_2_addresses
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": true,"isDefaultBilling": true}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] first_address_uid
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Save value to a variable: [data][1][id] second_address_uid
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${second_address_uid}
+ ... AND Response status code should be: 204
+
+#DELETE
+
+Delete_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/addresses
+ ... AND Response status code should be: 200
+ ... AND Response should contain the array of a certain size: [data] 1
+ ... AND Save value to a variable: [data][0][id] address_uid
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+
+#PATCH
+
+Update_customer_address_several_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ ... AND Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a PATCH request:
+ ... /customers/${yves_user.reference}/addresses/${address_uid}
+ ... {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${address_uid}
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${changed.address1}
+ And Response body parameter should be: [data][attributes][address2] ${changed.address2}
+ And Response body parameter should be: [data][attributes][address3] ${changed.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${changed.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_access/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_access/positive.robot
new file mode 100644
index 0000000..7d0c73e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_access/positive.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core
+
+
+*** Test Cases ***
+##### all negative and positive tests for this endpoint are already covered with other tests (e.g. abstract-product-prices checks that without token process are not accessible)
+Get_resources_customer_can_access
+ When I send a GET request: /customer-access
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] customer-access
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][resourceTypes]
+ ... ${restricted_content_qty}
+ And Response body parameter should be: [data][0][attributes][resourceTypes][0] abstract-product-prices
+ And Response body parameter should be: [data][0][attributes][resourceTypes][1] concrete-product-prices
+ And Response body parameter should be: [data][0][attributes][resourceTypes][2] checkout
+ And Response body parameter should be: [data][0][attributes][resourceTypes][3] checkout-data
+ And Response body parameter should be: [data][0][attributes][resourceTypes][4] guest-cart-items
+ And Response body has correct self link
+
+Access_restricted_resource_as_authorized_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract.volume_prices.sku}/abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract.volume_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/negative.robot
new file mode 100644
index 0000000..f13ad58
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/negative.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Customer_confirmation_with_wrong_confirmation_key
+ And I send a POST request:
+ ... /customer-confirmation
+ ... {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"39085d16b04b34265910c7ea2a35367ggh"}}}
+ Response status code should be: 422
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ And Response should return error code: 423
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_confirmation_key
+ And I send a POST request:
+ ... /customer-confirmation
+ ... {"data":{"type":"customer-confirmation","attributes":{"registrationKey":""}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_without_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_type
+ And I send a POST request:
+ ... /customer-confirmation
+ ... {"data":{"type":"","attributes":{"registrationKey":"607a17d1c673f461ca40002ea79fddc0"}}}
+ Response status code should be: 400
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_already_used_confirmation_key
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 423
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/positive.robot
new file mode 100644
index 0000000..d9e6cf3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_confirmation/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Customer_confirmation
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot
new file mode 100644
index 0000000..d95e2cc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot
@@ -0,0 +1,38 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Forgot_password_wrong_email_format
+ I send a POST request:
+ ... /customer-forgotten-password
+ ... {"data":{"type":"customer-forgotten-password","attributes":{"email":"123"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_empty_email
+ I send a POST request:
+ ... /customer-forgotten-password
+ ... {"data":{"type":"customer-forgotten-password","attributes":{"email":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_incorrect_type
+ I send a POST request:
+ ... /customer-forgotten-password
+ ... {"data":{"type":"customer","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot
new file mode 100644
index 0000000..f6fcd91
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot
@@ -0,0 +1,16 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Forgot_password_with_all_required_fields_and_valid_data
+ I send a POST request:
+ ... /customer-forgotten-password
+ ... {"data":{"type":"customer-forgotten-password","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/negative.robot
new file mode 100644
index 0000000..3a5b2d7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/negative.robot
@@ -0,0 +1,167 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Update_customer_password_with_not_equal_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field newPassword should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_data_type
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_current_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: newPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password_confirmation
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_non_autorizated_user
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_not_valid_user_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new_additional}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 408
+ And Response should return error message: Invalid password
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_short_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"test","confirmPassword":"test"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... newPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_long_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... newPassword => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_customer_reference
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"1234567890123","confirmPassword":"1234567890123"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_mandatory_fields
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/test123
+ ... {"data":{"type":"customer-password","attributes":{"newPassword":"${yves_user.password}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_invalid_access_token
+ Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/positive.robot
new file mode 100644
index 0000000..66d0da7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_password/positive.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Update_customer_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request:
+ ... /customer-password/${yves_eighth_user.reference}
+ ... {"data":{"type":"customer-password","attributes":{"password":"${yves_eighth_user.password}","newPassword":"${yves_eighth_user.password_new}","confirmPassword":"${yves_eighth_user.password_new}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new_additional}"}}}
+ Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+ And I send a POST request:
+ ... /access-tokens
+ ... {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new}"}}}
+ And Response status code should be: 201
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/negative.robot
new file mode 100644
index 0000000..00ce43b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/negative.robot
@@ -0,0 +1,134 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Restore_password_without_customer_id
+ I send a PATCH request:
+ ... /customer-restore-password/
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_type
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_restorePasswordKey
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 415
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Restore password key is not valid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_without_restorePasswordKey
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: restorePasswordKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_password_value
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_confirmation_password_value
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"${yves_user.password}","confirmPassword":""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_short_new_password
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"test","confirmPassword":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_long_new_password
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_not_equal_new_password_and_confirm_password
+ I send a PATCH request:
+ ... /customer-restore-password/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 406
+ And Response reason should be: Unprocessable Content
+ And Response should return error message:
+ ... Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_url
+ I send a PATCH request:
+ ... /customer-restorepassword/${yves_user.reference}
+ ... {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/positive.robot
new file mode 100644
index 0000000..c863f25
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customer_restore_password/positive.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Restore_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_ninth_user.first_name}","lastName":"${yves_ninth_user.last_name}","gender":"${gender.female}","salutation":"${yves_ninth_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_ninth_user.password}","confirmPassword":"${yves_ninth_user.password}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I send a POST request: /customer-forgotten-password {"data": {"type": "customer-forgotten-password","attributes": {"email":"${user_email}"}}}
+ ... AND Save the result of a SELECT DB query to a variable: select restore_password_key from spy_customer where customer_reference = '${user_reference_id}' restore_key
+ When I send a PATCH request:
+ ... /customer-restore-password/${user_reference_id}
+ ... {"data":{"type":"customer-restore-password","id":"${user_reference_id}","attributes":{"restorePasswordKey":"${restore_key}","password":"${yves_ninth_user.password_new}","confirmPassword":"${yves_ninth_user.password_new}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${user_email} ${yves_ninth_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/negative.robot
new file mode 100644
index 0000000..4da3bd3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/negative.robot
@@ -0,0 +1,375 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Create_a_customer_with_already_existing_email
+ When I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 400
+ And Response should return error message:
+ ... If this email address is already in use, you will receive a password reset link. Otherwise you must first validate your e-mail address to finish registration. Please check your e-mail.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_short_password
+ When I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"Test12!","confirmPassword":"Test12!","acceptedTerms":true}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message:
+ ... password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_long_password
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message:
+ ... password => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_equal_passwords
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"${yves_user.password_new}","confirmPassword":"1234567890123","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message:
+ ... Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_accepted_terms_and_coditions
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":false}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_type
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":false}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_values_for_required_fields
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... email => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_absent_type
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.first_name}+${random}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_wrong_email_format
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"test.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_missing_required_fields
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... acceptedTerms => This field is missing.
+ And Array in response should contain property with value: [errors] detail gender => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_without_gender_and_salutation
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => The value you selected is not a valid choice.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/DE35
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_cusomer_without_access_token
+ I send a GET request: /customers/${customer_reference.de_1}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_customer_with_access_token_from_another_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_second_user.reference}
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${customer_reference.de_1}
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${yves_user.reference}
+ ... {"data":{"type":"","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.female}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${yves_user.reference}
+ ... {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":false}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... firstName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... lastName => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... email => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_absent_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${yves_user.reference}
+ ... {"data":{"attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.female}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_invalid_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${yves_user.reference}
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... salutation => The value you selected is not a valid choice.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_without_access_token
+ I send a PATCH request:
+ ... /customers/DE--35
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.female}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_cusomer_without_access_token
+ I send a DELETE request: /customers/DE--35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/DE35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_with_access_token_from_another
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/${customer_reference.de_1}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/positive.robot
new file mode 100644
index 0000000..5a66324
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/customer_endpoints/customers/positive.robot
@@ -0,0 +1,127 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+
+*** Test Cases ***
+Create_customer
+ I send a POST request:
+ ... /customers/
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 201
+ And Save value to a variable: [data][id] user_reference_id
+ And Save value to a variable: [data][attributes][email] user_email
+ And Save the result of a SELECT DB query to a variable:
+ ... select registration_key from spy_customer where customer_reference = '${user_reference_id}'
+ ... confirmation_key
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${user_reference_id}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${user_email}
+ And Response body parameter should be: [data][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ [Teardown] Run Keywords I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${user_email} ${yves_user.password_new}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+New_customer_can_login_after_confirmation
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ I send a POST request:
+ ... /customer-confirmation
+ ... {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I get access token for the customer: ${user_email} ${yves_user.password_new}
+ And I set Headers: Authorization=${token}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_customer_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ And Response body has correct self link internal
+
+Update_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /customers/${yves_user.reference}
+ ... {"data":{"type":"customers","attributes":{"firstName":"${yves_second_user.first_name}","lastName":"${yves_second_user.last_name}","gender":"${gender.male}","salutation":"${yves_second_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 200
+ And Response body has correct self link internal
+ And I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][gender] ${gender.male}
+ [Teardown] Run Keywords I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 200
+ ... AND Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+
+Get_customer_array_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/
+ And Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] customers
+ And Response body parameter should be: [data][0][id] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][0][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][0][attributes][updatedAt]
+
+Delete_customer
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${email.name}${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${user_email} ${yves_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${user_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/negative.robot
new file mode 100644
index 0000000..a005f1e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/negative.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue promotions-discounts product-promotions
+
+
+*** Test Cases ***
+####### POST #######
+
+Adding_not_existing_voucher_code_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "419901","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "1111111"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response body parameter should not be EMPTY: [errors]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Adding_voucher_code_that_could_not_be_applied_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "464012","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Adding_voucher_code_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request:
+ ... /carts/invalidCartId/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Adding_voucher_without_access_token
+ [Setup] Get voucher code by discountId from Database: 3
+ And I send a POST request:
+ ... /carts/fake/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Adding_voucher_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization="fake"
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request:
+ ... /carts/invalidCartId/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+####### DELETE #######
+# Fails because of CC-16719
+
+Deleting_voucher_without_access_token
+ [Setup] Run Keywords I set Headers: Authorization=
+ ... AND Get voucher code by discountId from Database: 3
+ And I send a DELETE request: /carts/cart_id/vouchers/${discount_voucher_code}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Fails because of CC-16719
+
+Deleting_voucher_with_invalid_access_token
+ [Setup] Run Keywords I set Headers: Authorization="fake"
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a DELETE request: /carts/cart_id/vouchers/${discount_voucher_code}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Deleting_voucher_code_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a DELETE request: /carts/invalidCartId/vouchers/${discount_voucher_code}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/positive.robot
new file mode 100644
index 0000000..b51a4d6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/discount_endpoints/vouchers/positive.robot
@@ -0,0 +1,241 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart promotions-discounts product-promotions
+
+
+*** Test Cases ***
+#####POST#####
+
+Adding_voucher_code_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_brand_safescan.product_1.sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ When I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${voucher.brand_safescan_2_items}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #checking cart rule and vouchers in cart
+ And Response body parameter should contain:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Checking_voucher_is_applied_after_order_is_placed
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_brand_safescan.product_1.sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ When I send a POST request:
+ ... /checkout?include=orders
+ ... {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.with_brand_safescan.product_1.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [included][0][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #calculatedDiscounts - "10% off Safescan" discount
+ VAR ${discount_total_sum} ${voucher.brand_safescan_2_items}
+ And Response body parameter should not be EMPTY:
+ ... [included][0][attributes][calculatedDiscounts]["${discounts.id_4.name}"]
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["${discounts.id_4.name}"][displayName]
+ ... ${discounts.id_4.name}
+ And Response body parameter with rounding should be:
+ ... [included][0][attributes][calculatedDiscounts]["${discounts.id_4.name}"][sumAmount]
+ ... ${discount_total_sum}
+ And Response body parameter should contain:
+ ... [included][0][attributes][calculatedDiscounts]["${discounts.id_4.name}"][voucherCode]
+ ... ${discount_voucher_code}
+
+Adding_two_vouchers_with_different_priority_to_the_same_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_brand_safescan.product_2_and_white_color.sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ And Save value to a variable: [data][attributes][discounts][0][code] voucher_1
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Get voucher code by discountId from Database: 4
+ And I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ And Save value to a variable: [data][attributes][discounts][0][code] voucher_2
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][2]
+ And Response should contain the array of a certain size: [data][attributes][discounts] 3
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${voucher.brand_safescan_2_items}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #calculatedDiscounts - "10% off Safescan" discount
+ And Response body parameter should contain:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${voucher_2}
+ #calculatedDiscounts - "5% off White" discount
+ And Response body parameter should contain:
+ ... [data][attributes][discounts][1][displayName]
+ ... ${discounts.id_3.name}
+ And Response body parameter should contain: [data][attributes][discounts][1][code] ${voucher_1}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Adding_voucher_with_cart_rule_with_to_the_same_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_brand_safescan.product_1.sku}","quantity": 10}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ When I send a POST request:
+ ... /carts/${cart_id}/vouchers
+ ... {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${voucher.brand_safescan_2_items}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #checking cart rule and vouchers in cart
+ And Response body parameter should contain:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response body parameter should contain:
+ ... [data][attributes][discounts][1][displayName]
+ ... ${cart_rule_name_10_off_minimum_order}
+ And Response body parameter should contain: [data][attributes][discounts][1][code] None
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+
+Deleting_voucher_from_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_brand_safescan.product_2_and_white_color.sku}","quantity": 5}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][totals][grandTotal] grand_total
+ ... AND Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ ... AND Get voucher code by discountId from Database: 4
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cartId}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /carts/${cartId}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total}
+ And Response body parameter should NOT be:
+ ... [data][attributes][discounts][0][displayName]
+ ... ${discounts.id_4.name}
+ And Response body parameter should NOT be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/negative.robot
new file mode 100644
index 0000000..99c8257
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/negative.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-labels
+
+
+*** Test Cases ***
+Get_a_label_without_label_id
+ When I send a GET request: /product-labels
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1202
+ And Response should return error message: Product label id is missing.
+
+Get_a_label_with_non_existent_label_id
+ When I send a GET request: /product-labels/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/positive.robot
new file mode 100644
index 0000000..11f3949
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_labels/positive.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue alternative-products product product-labels discontinued-products
+
+
+*** Test Cases ***
+#####POST#####
+Get_manual_product_label_by_id
+ When I send a GET request: /product-labels/${labels.id_manual}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${labels.id_manual}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${labels.name_manual}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_new_product_label_by_id
+ When I send a GET request: /product-labels/${labels.id_new}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${labels.id_new}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${labels.name_new}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_sale_product_label_by_id
+ When I send a GET request: /product-labels/${labels.id_sale}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${labels.id_sale}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${labels.name_sale}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_discontinued_product_label_by_id
+ When I send a GET request: /product-labels/${labels.id_discontinued}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${labels.id_discontinued}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${labels.name_discontinued}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_alternative_product_label_by_id
+ When I send a GET request: /product-labels/${labels.id_alternative}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${labels.id_alternative}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${labels.name_alternative}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/negative.robot
new file mode 100644
index 0000000..7a9c440
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/negative.robot
@@ -0,0 +1,16 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Get_an_attribute_with_non_existent_attribute_id
+ When I send a GET request: /product-management-attributes/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4201
+ And Response should return error message: Attribute not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/positive.robot
new file mode 100644
index 0000000..d2ccb75
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_management_attributes/positive.robot
@@ -0,0 +1,165 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product
+
+
+*** Test Cases ***
+Get_all_product_management_attributes
+ When I send a GET request: /product-management-attributes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 50
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-management-attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes][key]
+ And Response body parameter should not be EMPTY: [data][0][attributes][inputType]
+ And Response body parameter should not be EMPTY: [data][0][attributes][allowInput]
+ And Response body parameter should be in: [data][0][attributes][allowInput] True False
+ And Response body parameter should be in: [data][0][attributes][isSuper] True False
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][value]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][localizedValues]
+ And Response body parameter should be in:
+ ... [data][0][attributes][values][0][localizedValues][0][localeName]
+ ... ${locale.DE.name} ${locale.EN.name}
+ And Response body parameter should not be EMPTY:
+ ... [data][0][attributes][values][0][localizedValues][0][translation]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain property with value in:
+ ... [data]
+ ... [attributes][allowInput]
+ ... True
+ ... False
+ And Each array element of array in response should contain property with value in:
+ ... [data]
+ ... [attributes][isSuper]
+ ... True
+ ... False
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][localizedKeys]
+ ... localeName
+ ... ${locale.DE.name}
+ ... ${locale.EN.name}
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][localizedKeys]
+ ... translation
+ And Each array element of nested array should contain property with value NOT in:
+ ... [data]
+ ... [attributes][localizedKeys]
+ ... translation
+ ... None
+ And Each array element of array in response should contain nested property: [data] [attributes] values
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][values]
+ ... value
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][values]
+ ... localizedValues
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_product_management_attribute_by_id_superattribute
+ When I send a GET request: /product-management-attributes/${product_management.superattribute_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] True
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][localeName]
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][translation]
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... translation
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values]
+ ... localizedValues
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... localeName
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_free_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... translation
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values]
+ ... localizedValues
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... localeName
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_non_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_no_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... translation
+ And Each array element of array in response should contain property:
+ ... [data][attributes][localizedKeys]
+ ... localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values]
+ ... localizedValues
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... localeName
+ And Each array element of array in response should contain property:
+ ... [data][attributes][values][0][localizedValues]
+ ... translation
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/negative.robot
new file mode 100644
index 0000000..3a371ce
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/negative.robot
@@ -0,0 +1,130 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-rating-reviews
+
+
+*** Test Cases ***
+Get_a_review_with_non_existent_review_id
+ When I send a GET request: /abstract-products/${abstract.with_review.sku}/product-reviews/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Product review is not found.
+
+Get_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_review_by_id_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews/78
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_a_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews/78
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Create_a_product_review_without_token
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Create_a_product_review_with_invalid_token
+ [Setup] I set Headers: Authorization=fake
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_a_product_review_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"type": "product-review","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_a_product_review_with_missing_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_a_product_review_with_empty_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"type": "product-reviews","attributes": {"rating": "","nickname": "","summary": "","description": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... rating => This value should be of type numeric.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... rating => This value should be greater than or equal to 1.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... summary => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... nickname => This value should not be blank.
+
+Create_a_product_review_with_missing_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... {"data": {"type": "product-reviews","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... summary => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... nickname => This field is missing.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/positive.robot
new file mode 100644
index 0000000..1785f4f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_reviews/positive.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-rating-reviews
+
+
+*** Test Cases ***
+Get_product_reviews
+ When I send a GET request: /abstract-products/${abstract.with_review.sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract.with_review.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] rating
+ And Each array element of array in response should contain nested property: [data] [attributes] nickname
+ And Each array element of array in response should contain nested property: [data] [attributes] summary
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... description
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_a_subset_of_product_reviews
+ When I send a GET request:
+ ... /abstract-products/${abstract.with_review.sku}/product-reviews?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][0][attributes][rating]
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Get_product_reviews_for_product_with_no_reviews
+ When I send a GET request:
+ ... /abstract-products/${abstract.available_products.with_stock_and_never_out_of_stock_sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_product_review_by_id
+ [Setup] Run Keywords I send a GET request: /abstract-products/${abstract.with_review.sku}/product-reviews
+ ... AND Save value to a variable: [data][0][id] review_id
+ When I send a GET request: /abstract-products/${abstract.with_review.sku}/product-reviews/${review_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract.with_review.qty}
+ And Response body parameter should be: [data][id] ${review_id}
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][attributes][rating]
+ And Response body parameter should have datatype: [data][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Create_a_product_review
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request:
+ ... /abstract-products/${abstract.with_options.sku}/product-reviews
+ ... {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 202
+ And Response reason should be: Accepted
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] review_id
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should be: [data][attributes][rating] ${review.default_rating}
+ And Response body parameter should be: [data][attributes][nickname] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][summary] ${review.title}
+ And Response body parameter should be: [data][attributes][description] ${review.text}
+ And Response body has correct self link for created entity: ${review_id}
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/negative.robot
new file mode 100644
index 0000000..47d60d9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/negative.robot
@@ -0,0 +1,32 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product tax
+
+
+*** Test Cases ***
+
+Get_a_tax_set_with_concrete_sku
+ When I send a GET request:
+ ... /abstract-products/${concrete.available_product.with_stock.product_1.sku}/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
+
+Get_a_tax_set_with_missing_sku
+ When I send a GET request: /abstract-products//product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_a_tax_set_with_non_existing_sku
+ When I send a GET request: /abstract-products/fake/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/positive.robot
new file mode 100644
index 0000000..1413312
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/product_tax_sets/positive.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product tax
+
+
+*** Test Cases ***
+Get_product_tax sets
+ When I send a GET request: /abstract-products/${abstract.with_review.sku}/product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-tax-sets
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response should contain the array larger than a certain size: [data][0][attributes][restTaxRates] 1
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] name
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] rate
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] country
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/negative.robot
new file mode 100644
index 0000000..aee0e3b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-relations
+
+
+*** Test Cases ***
+Get_related_products_without_abstract_SKU
+ When I send a GET request: /abstract-products//related-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_related_products_for_nonexistent_SKU
+ When I send a GET request: /abstract-products/not_a_SKU/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_related_products_for_concrete_SKU
+ When I send a GET request:
+ ... /abstract-products/${concrete.available_product.with_stock.product_1.sku}/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/positive.robot
new file mode 100644
index 0000000..9ad11c9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/related_products/positive.robot
@@ -0,0 +1,195 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-relations
+
+
+*** Test Cases ***
+Product_has_related_products
+ When I send a GET request:
+ ... /abstract-products/${abstract.product_with_relations.has_related_products.product_1.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${abstract.product_with_relations.has_related_products.product_2.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be:
+ ... [data][0][attributes][sku]
+ ... ${abstract.product_with_relations.has_related_products.product_2.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][name]
+ ... ${abstract.product_with_relations.has_related_products.product_2.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes][brand]
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][super_attributes]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][attributeMap][product_concrete_ids]
+ ... 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][attribute_variants]
+ ... 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][attribute_variant_map]
+ ... 0
+ And Response should contain the array of a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames][brand]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][sku]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... averageRating
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... reviewCount
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][name]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributes]
+ ... brand
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... superAttributesDefinition
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... superAttributes
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... attributeMap
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... super_attributes
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... product_concrete_ids
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... attribute_variants
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... metaKeywords
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... metaDescription
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... attributeNames
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeNames]
+ ... brand
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Product_has_related_products_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request:
+ ... /abstract-products/${abstract.product_with_relations.has_related_products.product_1.sku}/related-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][abstract-product-prices][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][abstract-product-image-sets][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][concrete-products][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][abstract-product-availabilities][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][product-tax-sets][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][product-options][data]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][category-nodes][data]
+ ... 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+
+Product_has_no_related_products
+ When I send a GET request: /abstract-products/${abstract.available_products.with_stock.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/negative.robot
new file mode 100644
index 0000000..83ba5c6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/negative.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-relations
+
+
+*** Test Cases ***
+Get_upselling_products_with_missing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=invalid
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_upselling_products_without_access_token
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_upselling_products_using_cart_of_other_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/positive.robot
new file mode 100644
index 0000000..5e32862
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/general_product_endpoints/upselling_products/positive.robot
@@ -0,0 +1,253 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product product-relations
+
+
+*** Test Cases ***
+Get_upselling_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_relations_upselling_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Response body parameter should be:
+ ... [data][0][id]
+ ... ${abstract.product_with_relations.has_related_products.has_upselling_product.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be:
+ ... [data][0][attributes][sku]
+ ... ${abstract.product_with_relations.has_related_products.has_upselling_product.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][name]
+ ... ${abstract.product_with_relations.has_related_products.has_upselling_product.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][super_attributes]
+ ... 0
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][attributeMap][product_concrete_ids]
+ ... 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][attribute_variants]
+ ... 0
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][attributeMap][attribute_variant_map]
+ ... 0
+ And Response should contain the array of a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_upselling_products_plus_includes
+ [Documentation] https://spryker.atlassian.net/browse/CC-31988
+ [Tags] skip-due-to-refactoring
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_relations_upselling_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request:
+ ... /carts/${cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-prices][data]
+ ... 1
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-image-sets][data]
+ ... 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][relationships][abstract-product-availabilities][data]
+ ... 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][product-options][data]
+ ... 1
+ And Response should contain the array larger than a certain size:
+ ... [data][0][relationships][category-nodes][data]
+ ... 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_upselling_products_for_cart_containing_multiple_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.with_relations_upselling_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.alternative_products.with_relations_upselling_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock.product_1.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][sku]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... averageRating
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... reviewCount
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][name]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][attributes]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... superAttributesDefinition
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... superAttributes
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... attributeMap
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... super_attributes
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... product_concrete_ids
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... attribute_variants
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][attributeMap]
+ ... attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... metaKeywords
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... metaDescription
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... attributeNames
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [attributes][attributeNames]
+ ... None
+ ... null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_upselling_products_for_cart_without_upselling_relations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock.product_1.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_upselling_products_for_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/negative.robot
new file mode 100644
index 0000000..f8cdbbf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue navigation spryker-core
+
+
+*** Test Cases ***
+Get_navigations_by_non_exist_id
+ When I send a GET request: /navigations/testNonExistNavigations
+ Then Response status code should be: 404
+ And Response should return error code: 1601
+ And Response should return error message: Navigation not found.
+
+Get_absent_navigations
+ When I send a GET request: /navigations
+ Then Response status code should be: 400
+ And Response should return error code: 1602
+ And Response should return error message: Navigation id not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/positive.robot
new file mode 100644
index 0000000..62fbf47
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/navigations_endpoints/navigations/positive.robot
@@ -0,0 +1,102 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core navigation category-management merchant-category
+
+
+*** Test Cases ***
+Get_navigation_tree_using_valid_navigation_key
+ When I send a GET request: /navigations/MAIN_NAVIGATION
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][isActive] bool
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] children
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][nodeType] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][title] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][children] list
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][nodeType]
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][title]
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... nodeType
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... cssClass
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... title
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... url
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... validFrom
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... validTo
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][attributes][nodes][0][children]
+ ... children
+ And Response body has correct self link internal
+
+Get_navigation_tree_using_valid_navigation_key_with_category_nodes_included
+ When I send a GET request: /navigations/MAIN_NAVIGATION?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Should Contain The Array Larger Than a Certain Size: [included] 0
+ And Response Should Contain The Array Larger Than a Certain Size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][category-nodes]
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][relationships][category-nodes][data]
+ ... type
+ And Each Array Element Of Array In Response Should Contain Property:
+ ... [data][relationships][category-nodes][data]
+ ... id
+ And Response body parameter should not be EMPTY: [included]
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ Each array element of array in response should contain nested property: [included] [links] self
+ And Each Array Element Of Array In Response Should Contain Property With Value:
+ ... [included]
+ ... type
+ ... category-nodes
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes nodeId
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes name
+ And Each Array Element Of Array In Response Should Contain Nested Property:
+ ... [included]
+ ... attributes
+ ... metaTitle
+ And Each Array Element Of Array In Response Should Contain Nested Property:
+ ... [included]
+ ... attributes
+ ... metaKeywords
+ And Each Array Element Of Array In Response Should Contain Nested Property:
+ ... [included]
+ ... attributes
+ ... metaDescription
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes isActive
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes order
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes url
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes children
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes parents
diff --git a/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/negative.robot
new file mode 100644
index 0000000..d03f2ae
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/negative.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue order-management spryker-core customer-access
+
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_order_by_order_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_with_invalid_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/fake_order_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+### Current test commented because it doesn't work while /orders endpoint is available
+#Get_order_without_order_id
+# [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+# ... AND I set Headers: Authorization=${token}
+# When I send a GET request: /orders/
+# Then Response status code should be: 404
+# And Response reason should be: Unprocessable Content
+# And Response should return error message: Missing order id
+# And Response should return error code: 1100
+
+Get_order_by_order_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+Get_customer_orders_list_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_customer_orders_list_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_customer_orders_list_with_invalid_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/yves_user.reference/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
diff --git a/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/positive.robot
new file mode 100644
index 0000000..8d83314
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/order_endpoints/orders/positive.robot
@@ -0,0 +1,907 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue cart checkout order-management merchant product product-bundles measurement-units packaging-units non-splittable-products shipment configurable-bundle configurable-product gift-cards spryker-core customer-access
+
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be:
+ ... [data][attributes][shippingAddress][salutation]
+ ... ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][unitTaxAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][sumTaxAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][unitDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][sumDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][unitDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][sumDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size:
+ ... [data][attributes][items][0][metadata][superAttributes]
+ ... 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be: [data][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][calculatedDiscounts][0][unitAmount]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][items][0][calculatedDiscounts][0][sumAmount]
+ ... 0
+ And Response body parameter should not be EMPTY:
+ ... [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY:
+ ... [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be:
+ ... [data][attributes][expenses][0][name]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body case-insensitive parameter should be:
+ ... [data][attributes][payments][0][paymentProvider]
+ ... ${payment_provider_name}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment_method_name}
+ #shipments
+ And Response body parameter should be:
+ ... [data][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.product_1.concrete_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${bundle_product.product_1.concrete_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Each array element of array in response should contain property with value:
+ ... [data][attributes][items]
+ ... bundleItemIdentifier
+ ... ${None}
+ And Each array element of array in response should contain property:
+ ... [data][attributes][items]
+ ... relatedBundleItemIdentifier
+ And Response body parameter should be: [data][attributes][items][0][name] ${bundle_product.product_2.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${bundle_product.product_2.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][1][name] ${bundle_product.product_3.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][1][sku]
+ ... ${bundle_product.product_3.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][2][name] ${bundle_product.product_4.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][2][sku]
+ ... ${bundle_product.product_4.concrete_sku}
+ #bundleItems
+ And Response body parameter should be:
+ ... [data][attributes][bundleItems][0][name]
+ ... ${bundle_product.product_1.name}
+ And Response body parameter should be:
+ ... [data][attributes][bundleItems][0][sku]
+ ... ${bundle_product.product_1.concrete_sku}
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumGrossPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRate] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][refundableAmount] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][canceledAmount] None
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][sumSubtotalAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][unitSubtotalAggregation]
+ ... 0
+ And Response body parameter should be:
+ ... [data][attributes][bundleItems][0][unitProductOptionPriceAggregation]
+ ... None
+ And Response body parameter should be:
+ ... [data][attributes][bundleItems][0][sumProductOptionPriceAggregation]
+ ... None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][unitDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][sumDiscountAmountAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][unitDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][sumDiscountAmountFullAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][unitPriceToPayAggregation]
+ ... 0
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][sumPriceToPayAggregation]
+ ... 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRateAverageAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][orderReference] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][uuid] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][isReturnable] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][idShipment] None
+ And Response body parameter should be greater than:
+ ... [data][attributes][bundleItems][0][bundleItemIdentifier]
+ ... 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size:
+ ... [data][attributes][bundleItems][0][metadata][superAttributes]
+ ... 0
+ And Response body parameter should not be EMPTY: [data][attributes][bundleItems][0][metadata][image]
+ And Response body parameter should be: [data][attributes][bundleItems][0][salesUnit] None
+ And Response should contain the array of a certain size:
+ ... [data][attributes][bundleItems][0][calculatedDiscounts]
+ ... 0
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][amount] None
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_sales_unit
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a GET request: /concrete-products/${concrete.random_weight.sku1}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.random_weight.sku1}","quantity": 6,"salesUnit": {"id": "${sales_unit_id}","amount": 9}}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.random_weight.sku1}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${concrete.random_weight.name1}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${concrete.random_weight.sku1}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items] 6
+ And Response body parameter should be:
+ ... [data][attributes][items][0][salesUnit][conversion]
+ ... ${concrete.random_weight.conversion1}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][salesUnit][precision]
+ ... ${concrete.random_weight.precision1}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][salesUnit][productMeasurementUnit][name]
+ ... ${packaging_unit.m_name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][salesUnit][productMeasurementUnit][code]
+ ... ${packaging_unit.m}
+ And Response body parameter should be: [data][attributes][items][0][amount] ${concrete.random_weight.amount1}
+
+Get_order_by_order_id_with_different_items_and_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] first_item_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 2}}}
+ ... AND Save value to a variable: [included][1][id] second_item_id
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${first_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${second_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be: [data][attributes][items][2][name] ${concrete.with_options.name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][2][quantity] 1
+
+Get_order_by_order_id_with_nonsplit_item
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 10}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 1
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 10
+
+Get_order_by_order_id_with_mode.net_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 20}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 2},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.chf.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 20
+ #shipments
+ And Response body parameter should be:
+ ... [data][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method2.name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.chf.code}
+
+Get_order_by_order_id_with_split_shipment
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] first_item_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] second_item_id
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${first_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${second_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_split_shipment_&_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] first_item_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete.with_options.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] second_item_id
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment_method_name}","paymentProviderName": "${payment_provider_name}"}],"shipments": [{"items": ["${first_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${second_item_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}?include=order-shipments
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be:
+ ... [data][attributes][items][0][name]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.name}
+ And Response body parameter should be:
+ ... [data][attributes][items][0][sku]
+ ... ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value:
+ ... [data][relationships][order-shipments][data]
+ ... type
+ ... order-shipments
+ And Each array element of array in response should contain property:
+ ... [data][relationships][order-shipments][data]
+ ... id
+ And Response should contain the array of a certain size: [included] 2
+ #included 1
+ And Response body parameter should be: [included][0][type] order-shipments
+ And Response body parameter should be greater than: [included][0][id] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][itemUuids][0]
+ And Response body parameter should be:
+ ... [included][0][attributes][methodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be: [included][0][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be:
+ ... [included][0][attributes][requestedDeliveryDate]
+ ... ${shipment.delivery_date}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][salutation]
+ ... ${yves_user.salutation}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][firstName]
+ ... ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][lastName]
+ ... ${yves_user.last_name}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address1]
+ ... ${default.address1}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address2]
+ ... ${default.address2}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][address3]
+ ... ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be:
+ ... [included][0][attributes][shippingAddress][iso2Code]
+ ... ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][0][links]
+ #included 2
+ And Response body parameter should be: [included][1][type] order-shipments
+ And Response body parameter should be greater than: [included][1][id] 0
+ And Response body parameter should not be EMPTY: [included][1][attributes][itemUuids][0]
+ And Response body parameter should be:
+ ... [included][1][attributes][methodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be: [included][1][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][1][attributes][requestedDeliveryDate] None
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][salutation]
+ ... ${yves_user.salutation}
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][firstName]
+ ... ${yves_user.first_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][middleName] None
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][lastName]
+ ... ${yves_user.last_name}
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][address1]
+ ... ${changed.address1}
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][address2]
+ ... ${changed.address2}
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][address3]
+ ... ${changed.address3}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][phone] ${changed.phone}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be:
+ ... [included][1][attributes][shippingAddress][iso2Code]
+ ... ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][1][links]
+
+Get_order_by_order_id_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 3}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should be:
+ ... [data][attributes][totals][expenseTotal]
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 30000
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ #shipments
+ And Response body parameter should be:
+ ... [data][attributes][shipments][0][shipmentMethodName]
+ ... ${shipment.shipment_method1.name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be:
+ ... [data][attributes][shipments][0][defaultGrossPrice]
+ ... ${discounts.discount_3.total_sum}
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... sumAmount: ${discounts.discount_3.total_sum}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... displayName: ${discounts.discount_3.name}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... description: ${discounts.discount_3.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 1
+
+Get_order_by_order_id_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_1.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_2.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount.product_3.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${discount.product_1.sku}", "${discount.product_2.sku}", "${discount.product_3.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount.product_1.total_sum_of_discounts}
+ ... +
+ ... ${discount.product_2.total_sum_of_discounts}
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount_total_sum}
+ ... +
+ ... ${discount.product_3.with_10_percent_discount_amount}
+ And Perform arithmetical calculation with two arguments:
+ ... discount_total_sum
+ ... ${discount_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][discountTotal]
+ ... ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${sub_total_sum}
+ ... -
+ ... ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments:
+ ... grand_total_sum
+ ... ${grand_total_sum}
+ ... +
+ ... ${expense_total_sum}
+ And Response body parameter with rounding should be:
+ ... [data][attributes][totals][grandTotal]
+ ... ${grand_total_sum}
+ #item 1, 2, 3 - "20% off storage" discount, "10% off minimum order" discount
+ And Response should contain the array of a certain size: [data][attributes][items][0][calculatedDiscounts] 2
+ And Response body parameter should be: [data][attributes][items][0][name] ${discount.product_1.name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${discount.product_1.sku}
+ And Response body parameter should be in:
+ ... [data][attributes][items][0][calculatedDiscounts][0][unitAmount]
+ ... ${discount.product_1.with_discount_20_percent_off_storage} ${discount.product_1.with_discount_10_percent_off_minimum_order} ${discount.product_3.with_10_percent_discount_amount} ${discount.product_2.with_discount_20_percent_off_storage} ${discount.product_2.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [data][attributes][items][0][calculatedDiscounts][0][sumAmount]
+ ... ${discount.product_1.with_discount_20_percent_off_storage} ${discount.product_1.with_discount_10_percent_off_minimum_order} ${discount.product_3.with_10_percent_discount_amount} ${discount.product_2.with_discount_20_percent_off_storage} ${discount.product_2.with_discount_10_percent_off_minimum_order}
+ And Response body parameter should be in:
+ ... [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ ... ${discounts.discount_1.name} ${discounts.discount_2.name} ${discounts.discount_3.name}
+ And Response body parameter should be in:
+ ... [data][attributes][items][0][calculatedDiscounts][0][description]
+ ... ${discounts.discount_1.description} ${discounts.discount_2.description} ${discounts.discount_3.description}
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... sumAmount: ${discounts.discount_1.total_sum_for_products_1_and_2}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... displayName: ${discounts.discount_2.name}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... description: ${discounts.discount_2.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 3
+ #calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... sumAmount: ${discounts.discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... displayName: ${discounts.discount_2.name}
+ And Response body parameter should contain:
+ ... [data][attributes][calculatedDiscounts]
+ ... description: ${discounts.discount_2.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 3
+
+Get_customer_orders_list_without_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ When I send a GET request: /orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... expenseTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... discountTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... taxTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... subtotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... grandTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... canceledTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_customer_orders_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... expenseTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... discountTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... taxTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... subtotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... grandTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... canceledTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_customer_orders_list_without_order_id_with_pagination
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock_and_never_out_of_stock.sku}"]}}}
+ ... AND I send a GET request: /orders
+ ... AND Save value to a variable: [data][2][id] order_id
+ When I send a GET request: /customers/${yves_user.reference}/orders?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] orders
+ And Response body parameter should be: [data][0][id] ${order_id}
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... expenseTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... discountTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... taxTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... subtotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... grandTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... canceledTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][totals]
+ ... remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
diff --git a/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/return_reasons/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/return_reasons/positive.robot
new file mode 100644
index 0000000..fb53d66
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/return_reasons/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue return-management
+
+
+*** Test Cases ***
+#GET requests
+Get_return_reason
+ When I send a GET request: /return-reasons
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type return-reasons
+ And Each array element of array in response should contain nested property: [data] [attributes] reason
+ And Response should contain the array of a certain size: [data] ${return_reason.qty}
+ And Each array element of array in response should contain nested property with value: [data] [id] None
+ And Each array element of array in response should contain property with value NOT in:
+ ... [data]
+ ... [links][self]
+ ... None
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/negative.robot
new file mode 100644
index 0000000..c65b9e1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/negative.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue return-management checkout cart spryker-core refunds
+
+
+*** Test Cases ***
+Create_a_return_with_order_is_not_returnable
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"1"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock.product_1.sku}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][items][0][uuid] returnableSalesOrderItemUuid
+ When I send a POST request:
+ ... /returns
+ ... {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${returnableSalesOrderItemUuid}","reason":"${return_reason.damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Retrieves_a_return_with_non_exists_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /returns/fake_returns_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find return by the given return reference."
+ And Response should return error code: 3602
+
+Retrieves_a_return_with_missing_auth_token
+ When I send a GET request: /returns/DE--21-R1
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_list_of_returns_with_missing_auth_token
+ When I send a GET request: /returns
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
diff --git a/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/positive.robot
new file mode 100644
index 0000000..1fcb139
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/returns_endpoints/returns/positive.robot
@@ -0,0 +1,157 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue return-management checkout cart spryker-core refunds
+
+
+*** Test Cases ***
+Create_a_return
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][id] item_id_return1
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return1}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason.damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][id] item_id_return1
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return1}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason.damaged}"}]}}}
+ And Save value to a variable: [data][id] returnId
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be:
+ ... [data][attributes][returnTotals][remunerationTotal]
+ ... ${refundable_amount}
+ And Response body has correct self link for created entity: ${returnId}
+
+Retrieves_return_by_id_with_returns_items_included
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"1"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock.product_1.sku}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason.damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be:
+ ... [data][attributes][returnTotals][remunerationTotal]
+ ... ${refundable_amount}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][return-items]
+ And Each array element of array in response should contain property:
+ ... [data][relationships][return-items][data]
+ ... type
+ And Each array element of array in response should contain property:
+ ... [data][relationships][return-items][data]
+ ... id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain nested property: [included] [attributes] uuid
+ And Each array element of array in response should contain property with value:
+ ... [included]
+ ... type
+ ... return-items
+ And Each array element of array in response should contain property with value in:
+ ... [included]
+ ... [attributes][orderItemUuid]
+ ... ${Uuid}
+ ... ${Uuid}
+ And Each array element of array in response should contain property with value in:
+ ... [included]
+ ... [attributes][reason]
+ ... ${return_reason.damaged}
+ ... ${return_reason.damaged}
+ And Response body has correct self link internal
+
+Retrieves_list_of_returns
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"1"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete.available_product.with_stock.product_1.sku}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason.damaged}"}]}}}
+ When I send a GET request: /returns
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... customerReference
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... returnTotals
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][returnTotals]
+ ... refundTotal
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][returnTotals]
+ ... remunerationTotal
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/negative.robot
new file mode 100644
index 0000000..9e2d0b7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue search catalog
+
+
+*** Test Cases ***
+Search_without_query_parameter
+ When I send a GET request: /catalog-search?
+ Then Response status code should be: 200
diff --git a/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..5a1d969
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,945 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue search catalog product
+
+
+*** Test Cases ***
+##### SEARCH PARAMETERS #####
+
+Search_with_empty_search_criteria_all_default_values_check
+ When I send a GET request: /catalog-search?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ #Sorting
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][sort][sortParamNames]
+ ... ${default_qty.sorting_options}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][sort][sortParamLocalizedNames]
+ ... ${default_qty.sorting_options}
+ And Response body parameter should contain: [data][0][attributes] currentSortParam
+ And Response body parameter should contain: [data][0][attributes] currentSortOrder
+ #Pagination
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response body parameter should be:
+ ... [data][0][attributes][pagination][config][defaultItemsPerPage]
+ ... ${ipp.default}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][pagination][config][validItemsPerPageOptions]
+ ... 3
+ And Response body parameter should contain:
+ ... [data][0][attributes][pagination][config][validItemsPerPageOptions]
+ ... ${ipp.default}
+ And Response body parameter should contain:
+ ... [data][0][attributes][pagination][config][validItemsPerPageOptions]
+ ... ${ipp.middle}
+ And Response body parameter should contain:
+ ... [data][0][attributes][pagination][config][validItemsPerPageOptions]
+ ... ${ipp.biggest}
+ #Abstract products
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... abstractSku
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... price
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... abstractName
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... prices
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... images
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][abstractProducts]
+ ... abstractSku
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][code]
+ ... ${currency.eur.code}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][symbol]
+ ... ${currency.eur.symbol}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][name]
+ ... ${currency.eur.name}
+ And Array element should contain property with value greater than at least once:
+ ... [data][0][attributes][abstractProducts][0][prices] DEFAULT
+ ... 1
+ # FIlters - all filters are NOT applied
+ And Each array element should contain property with value: [data][0][attributes][valueFacets] activeValue None
+ #Filters - category
+ And Response body parameter should contain: [data][0][attributes] valueFacets
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][name] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][localizedName] Categories
+ And Response should contain the array of size in:
+ ... [data][0][attributes][valueFacets][0][values]
+ ... ${default_qty.categories}
+ ... ${default_qty.categories_ssp}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][isMultiValued] False
+ #Filters - labels
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][name] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][localizedName] Product Labels
+ And Response should contain the array of size in:
+ ... [data][0][attributes][valueFacets][1][values]
+ ... ${default_qty.labels}
+ ... ${default_qty.labels_ssp}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][isMultiValued] True
+ #Filters - color
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] name farbe
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] localizedName Color
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values ${default_qty.colors}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][isMultiValued] True
+ # #Filters - material
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] name material
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] localizedName Material
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values ${default_qty.materials}
+ # #Filters - brand
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] name brand
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] localizedName Brand
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values ${default_qty.brands}
+ # #Filters - rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][name] rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][localizedName] Product Ratings
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][min] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][max] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][isMultiValued] False
+ # #Filters - category tree
+ And Response should contain the array of size in:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... ${category_tree_branches_qty}
+ ... ${category_tree_branches_qty_ssp}
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... nodeId
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... name
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... docCount
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... children
+ # #Selflinks
+ And Response body has correct self link
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_by_attribute_that_does_not_return_products
+ When I send a GET request: /catalog-search?q=fake
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 0
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 0
+ And Response body has correct self link
+
+Search_by_concrete_sku
+ When I send a GET request: /catalog-search?q=${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ When I send a GET request: /catalog-search?q=${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.alternative_products.product_1.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values 1
+ And Response body has correct self link
+
+Search_by_abstract_sku
+ When I send a GET request: /catalog-search?q=${abstract.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.alternative_products.product_1.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values 1
+ And Response body has correct self link
+
+Search_by_full_name
+ When I send a GET request: /catalog-search?q=${abstract.alternative_products.product_1.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.alternative_products.product_1.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][valueFacets][0][values]
+ ... 4
+ #labels
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][valueFacets][1][values]
+ ... 2
+ #brand
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][valueFacets][4][values]
+ ... 1
+ And Response body has correct self link
+
+Search_by_name_substring
+ When I send a GET request: /catalog-search?q=USB
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should NOT be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should NOT be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.alternative_products.product_1.name}
+ #categories
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][valueFacets][0][values]
+ ... 4
+ #labels
+ And Response should contain the array larger than a certain size:
+ ... [data][0][attributes][valueFacets][1][values]
+ ... 2
+ #brand
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values 8
+ And Response body has correct self link
+
+Search_by_attribute_(brand)
+ When I send a GET request: /catalog-search?q=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should contain:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${brand_1}
+ #brand
+ And Response should contain a nested array of a certain size at least once: [data][0][attributes][valueFacets] values 1
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body has correct self link
+
+Search_by_several_attributes
+ When I send a GET request: /catalog-search?q=${color_3}+${material_3}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 20
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+
+#### FILTERING #####
+
+Filter_by_rating_only_min
+ When I send a GET request: /catalog-search?q=&rating[min]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 20
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.max}
+
+Filter_by_rating_only_max
+ When I send a GET request: /catalog-search?q=&rating[max]=${default_rating.min}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.min}
+
+Filter_by_rating_Min_max
+ When I send a GET request: /catalog-search?q=&rating[min]=3&rating[max]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 3
+
+Filter_by_brand_one_brand
+ When I send a GET request: /catalog-search?q=&brand=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue ${brand_1}
+ And Response body has correct self link
+
+Filter_by_brand_two_brands
+ When I send a GET request: /catalog-search?q=&brand[]=${brand_2}&brand[]=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 38
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${brand_1}
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${brand_2}
+
+Filter_by_brand_empty_brand
+ When I send a GET request: /catalog-search?q=&brand=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue ${EMPTY}
+ And Response body has correct self link
+
+Filter_by_brand_non_existing_brand
+ When I send a GET request: /catalog-search?q=&brand=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue test123
+ And Response body has correct self link
+
+Filter_by_label_one_label
+ When I send a GET request: /catalog-search?q=&label=${label.manual}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 5
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 5
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] ${label.manual}
+ And Response body has correct self link
+
+Filter_by_label_two_labels
+ When I send a GET request: /catalog-search?q=&label[]=${label.new}&label[]=${label.manual}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 39
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${label.new}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][1] ${label.manual}
+
+Filter_by_label_non_existing_label
+ When I send a GET request: /catalog-search?q=&label[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] test123
+
+Filter_by_label_empty_label
+ When I send a GET request: /catalog-search?q=&label[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${EMPTY}
+
+Filter_by_color_one_color
+ When I send a GET request: /catalog-search?q=&farbe=${color_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 4
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 4
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue ${color_1}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][0]
+ ... ${default_qty.categories}
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][3]
+ ... ${default_qty.materials}
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][4]
+ ... ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_color_two_colors
+ When I send a GET request: /catalog-search?q=&farbe[]=${color_1}&farbe[]=${color_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 10
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${color_1}
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${color_2}
+
+Filter_by_color_non_existing_color
+ When I send a GET request: /catalog-search?q=&farbe[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue test123
+
+Filter_by_color_empty_color
+ When I send a GET request: /catalog-search?q=&farbe[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${EMPTY}
+
+Filter_by_material_one_material
+ When I send a GET request: /catalog-search?q=&material=${material_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 4
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 4
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue ${material_1}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][0]
+ ... ${default_qty.categories}
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][2]
+ ... ${default_qty.colors}
+ And Response should contain the array smaller than a certain size:
+ ... [data][0][attributes][valueFacets][4]
+ ... ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_material_two_materials
+ When I send a GET request: /catalog-search?q=&material[]=${material_1}&material[]=${material_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 15
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${material_1}
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue ${material_2}
+
+Filter_by_material_non_existing_material
+ When I send a GET request: /catalog-search?q=&material[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Array element should contain property or array value at least once: [data][0][attributes][valueFacets] activeValue test123
+
+Filter_by_material_empty_material
+ When I send a GET request: /catalog-search?q=&material[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] ${EMPTY}
+
+Filter_by_valid_main_category
+ When I send a GET request: /catalog-search?q=&category=${category_lvl1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl1.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl1.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of size in:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... ${category_tree_branches_qty}
+ ... ${category_tree_branches_qty_ssp}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][docCount]
+ ... ${category_lvl1.qty}
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][docCount]
+ ... 56
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][1][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][1][docCount]
+ ... 39
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][children][0][docCount]
+ ... 28
+ And Response body has correct self link
+
+Filter_by_valid_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl2.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${category_lvl2.qty_approx}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl2.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of size in:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... ${category_tree_branches_qty}
+ ... ${category_tree_branches_qty_ssp}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Array element should contain property or array value at least once: [data][0][attributes][categoryTreeFilter] docCount ${category_lvl2.qty}
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][docCount]
+ ... ${category_lvl2.qty}
+ And Response body parameter should be either: [data][0][attributes][categoryTreeFilter][3][children][1][docCount] [data][0][attributes][categoryTreeFilter][4][children][1][docCount] 0
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][children][0][docCount]
+ ... 28
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][children][0][docCount]
+ ... 28
+ And Response body has correct self link
+
+Filter_by_valid_sub_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl3.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl3.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl3.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of size in:
+ ... [data][0][attributes][categoryTreeFilter]
+ ... ${category_tree_branches_qty}
+ ... ${category_tree_branches_qty_ssp}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][docCount]
+ ... ${category_lvl3.qty}
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][docCount]
+ ... ${category_lvl3.qty}
+ And Response body parameter should be either: [data][0][attributes][categoryTreeFilter][3][children][1][docCount] [data][0][attributes][categoryTreeFilter][4][children][1][docCount] 0
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][children][0][docCount]
+ ... ${category_lvl3.qty}
+ And Response body parameter should be either:
+ ... [data][0][attributes][categoryTreeFilter][3][children][0][children][1][docCount]
+ ... [data][0][attributes][categoryTreeFilter][4][children][0][children][1][docCount]
+ ... 0
+ And Response body has correct self link
+
+Search_with_specific_currency
+ When I send a GET request: /catalog-search?q=¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ ... 416
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][code]
+ ... ${currency.chf.code}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][symbol]
+ ... ${currency.chf.symbol}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][prices][0][currency][name]
+ ... ${currency.chf.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+##### PAGINATION AND SORTING #####
+
+Search_set_specific_page_with_ipp.default
+ # here page 4 is selected using offset because 36/12=3 full pages, search shows the next page after the offset
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.default}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 4
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response body parameter should be:
+ ... [data][0][attributes][pagination][config][defaultItemsPerPage]
+ ... ${ipp.default}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_specific_page_and_nonipp.default
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.middle}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 2
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 18
+ And Response body parameter should be:
+ ... [data][0][attributes][pagination][config][defaultItemsPerPage]
+ ... ${ipp.default}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.middle}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_last_page_and_nonipp.default
+ When I send a GET request:
+ ... /catalog-search?q=&page[limit]=${ipp.biggest}&page[offset]=${total_number_of_products_in_search}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 12
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 12
+ And Response body parameter should be:
+ ... [data][0][attributes][pagination][config][defaultItemsPerPage]
+ ... ${ipp.default}
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+
+Search_set_invalid_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=18&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be in:
+ ... [data][0][attributes][pagination][numFound]
+ ... ${total_number_of_products_in_search}
+ ... ${total_number_of_products_in_search_ssp}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be in: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages} ${default_qty.ipp_pages_ssp}
+ And Response body parameter should be:
+ ... [data][0][attributes][pagination][config][defaultItemsPerPage]
+ ... ${ipp.default}
+ And Response should contain the array of a certain size:
+ ... [data][0][attributes][abstractProducts]
+ ... ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_sort_by_name_asc
+ When I send a GET request: /catalog-search?q=&sort=name_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] A
+ And Response body has correct self link
+
+Search_sort_by_name_desc
+ When I send a GET request: /catalog-search?q=&sort=name_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] X
+ And Response body has correct self link
+
+Search_sort_by_rating
+ When I send a GET request: /catalog-search?q=&sort=rating
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] rating
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract_sku_highest_rating}
+ And Response body has correct self link
+
+Search_sort_by_price_asc
+ When I send a GET request: /catalog-search?q=&sort=price_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 50
+ And Response body has correct self link
+
+Search_sort_by_price_desc
+ When I send a GET request: /catalog-search?q=&sort=price_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10000
+ And Response body has correct self link
+
+Search_sort_by_price_filter_query_parameter_and_pagination
+ When I send a GET request:
+ ... /catalog-search?q=soe&sort=price_desc&brand=${brand_1}&page[limit]=${ipp.middle}&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 18
+ And Array element should contain property with value at least once: [data][0][attributes][valueFacets] activeValue ${brand_1}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 5000
+
+Search_by_abstract_sku_with_abstract_include
+ When I send a GET request:
+ ... /catalog-search?q=${abstract.alternative_products.product_1.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.alternative_products.product_1.name}
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-products][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract.alternative_products.product_1.sku}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot
new file mode 100644
index 0000000..a51872e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot
@@ -0,0 +1,329 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue search catalog product discontinued-products
+
+
+*** Test Cases ***
+#GET requests
+
+Get_search_suggestions_without_query_parameter
+ [Documentation] There is a bug https://spryker.atlassian.net/browse/CC-15983
+ When I send a GET request: /catalog-search-suggestions
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_empty_q_parameter
+ When I send a GET request: /catalog-search-suggestions?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_non_existing_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=000000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_discontinued_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be:
+ ... [data][0][attributes][completion]
+ ... ${concrete.alternative_products.product_1.sku}
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${concrete.alternative_products.product_1.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_all_attributes_data
+ When I send a GET request: /catalog-search-suggestions?q=${concrete.alternative_products.product_1.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be:
+ ... [data][0][attributes][completion]
+ ... ${concrete.alternative_products.product_1.name_in_lower_case}
+ And Each array element of array in response should contain property: [data][0][attributes][categories] name
+ And Each array element of array in response should contain property: [data][0][attributes][categories] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] url
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][abstractSku]
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${concrete.alternative_products.product_1.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter shouldnot be EMPTY: [data][0][attributes][abstractProducts][1][abstractSku]
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][1][abstractSku]
+ ... ${abstract.alternative_products.product_3.sku}
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts]
+ ... price
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts]
+ ... abstractName
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts]
+ ... abstractSku
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts]
+ ... url
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts]
+ ... images
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryCollection]
+ ... name
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][categoryCollection]
+ ... url
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][cmsPageCollection]
+ ... name
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][cmsPageCollection]
+ ... url
+ And Response body has correct self link
+
+Get_search_suggestions_with_few_symbols
+ When I send a GET request: /catalog-search-suggestions?q=soe
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Each array element of array in response should contain value: [data][0][attributes][completion] soe
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] soe
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${abstract.available_products.with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.available_products.with_stock.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.available_products.with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts][0][images]
+ ... externalUrlSmall
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts][0][images]
+ ... externalUrlLarge
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_concrete_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete.alternative_products.product_1.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be:
+ ... [data][0][attributes][completion]
+ ... ${concrete.alternative_products.product_1.sku}
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${concrete.alternative_products.product_1.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.alternative_products.product_1.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_pages
+ When I send a GET request: /catalog-search-suggestions?q=${cms_page.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${cms_page.name_in_lower_case}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][name] ${cms_page.name}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][url] ${cms_page.url_en}
+ And Response body has correct self link
+
+Get_search_suggestions_with_category_collection
+ When I send a GET request: /catalog-search-suggestions?q=${category_collection.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be:
+ ... [data][0][attributes][categoryCollection][0][name]
+ ... ${category_collection.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][categoryCollection][0][url]
+ ... ${category_collection.url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_page_collection
+ When I send a GET request: /catalog-search-suggestions?q=${cms_page.collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be:
+ ... [data][0][attributes][cmsPageCollection][0][name]
+ ... ${cms_page.collection_name}
+ And Response body parameter should be:
+ ... [data][0][attributes][cmsPageCollection][0][url]
+ ... ${cms_page.collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_currency
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][completion]
+ ... ${brand_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Array element should contain property with value at least once: [data][0][attributes][abstractProducts] price ${${abstract.alternative_products.product_3.price_chf}}
+ And Response body has correct self link
+
+Get_search_suggestions_with_color
+ When I send a GET request: /catalog-search-suggestions?q=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value:
+ ... [data][0][attributes][completion]
+ ... ${color_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku_and_included_abstract_products
+ When I send a GET request:
+ ... /catalog-search-suggestions?q=${abstract.available_products.with_stock.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractName]
+ ... ${abstract.available_products.with_stock.name}
+ And Response body parameter should be:
+ ... [data][0][attributes][abstractProducts][0][abstractSku]
+ ... ${abstract.available_products.with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts][0][images]
+ ... externalUrlSmall
+ And Each array element of array in response should contain property:
+ ... [data][0][attributes][abstractProducts][0][images]
+ ... externalUrlLarge
+ And Response body parameter should be:
+ ... [data][0][relationships][abstract-products][data][0][type]
+ ... abstract-products
+ And Response body parameter should be:
+ ... [data][0][relationships][abstract-products][data][0][id]
+ ... ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be: [included][0][type] abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be:
+ ... [included][0][attributes][sku]
+ ... ${abstract.available_products.with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should be:
+ ... [included][0][attributes][name]
+ ... ${abstract.available_products.with_stock.name}
+ And Response body parameter should be:
+ ... [included][0][attributes][description]
+ ... ${abstract.available_products.with_stock.description}
+ And Response body parameter should be: [included][0][attributes][attributes][norm] ${norm_1}
+ And Response body parameter should be: [included][0][attributes][attributes][preiseinheit] ${price_unit_1}
+ And Response body parameter should be: [included][0][attributes][attributes][reihenverbinder] No
+ And Response body parameter should be: [included][0][attributes][attributes][stapelbar] No
+ And Response body parameter should be:
+ ... [included][0][attributes][attributes][rollenausfuehrung]
+ ... ${rollenausfuehrung_1}
+ And Response body parameter should be: [included][0][attributes][attributes][brand] ${brand_4}
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributes] 1
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][attributeMap][super_attributes]
+ ... 1
+ And Response body parameter should be:
+ ... [included][0][attributes][attributeMap][product_concrete_ids]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][attributeMap][attribute_variants]
+ ... 0
+ And Response should contain the array of a certain size:
+ ... [included][0][attributes][attributeMap][attribute_variant_map]
+ ... 1
+ And Response body parameter should be:
+ ... [included][0][attributes][metaKeywords]
+ ... ${concrete.available_product.with_stock.product_1.meta_keywords}
+ And Response body parameter should be:
+ ... [included][0][attributes][metaDescription]
+ ... ${concrete.available_product.with_stock.product_1.meta_description}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot
new file mode 100644
index 0000000..86cb5a7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot
@@ -0,0 +1,851 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue shopping-lists product bundle-products configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list_without_access_token
+ I send a POST request:
+ ... /shopping-lists/${shopping_list_1st.id}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Add_a_concrete_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ I send a POST request:
+ ... /shopping-lists/${shopping_list_1st.id}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Add_a_product_to_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists/shoppingListId/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+#Bug is already created and resolved CC-19379 but we need integration to b2b
+
+Add_a_product_with_non_existing_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"sku${random}","quantity":1}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1508
+ And Response should return error message: Concrete product not found.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":0}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_negaive_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":-1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_too_big_amount_of_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":99999999999999999999}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+#Bug is already created and resolved CC-19379 but we need integration to b2b
+
+Add_an_abstract_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.abstract_sku}","quantity":1}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1508
+ And Response should return error message: Concrete product not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_sku_value_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"","quantity":1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_invalid_data_for_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_shopping_list_id_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Add_a_concrete_product_to_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+#https://spryker.atlassian.net/browse/CC-16674
+
+Add_a_concrete_product_to_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists/${sharedShoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+
+Update_product_to_the_shopping_list_without_access_token
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_product_in_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Update_product_in_the_shopping_list_withot_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists//shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_quantity_of_the_product_at_the_shopping_list_to_zero
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":0}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Update_product_quntity_at_the_shopping_list_to_non_digit_value
+ [Documentation] Created a new bug CC-22842 as current error message is: "quantity => This value should be less than 2147483647." and not This value should be greater than 0.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be of type integer.
+ # And Array in response should contain property with value:
+ # ... [errors]
+ # ... detail
+ # ... quantity => This value should be greater than 0.
+
+
+Update_product_quntity_at_the_shopping_list_to_not_allowed_qty
+ [Documentation] Created a new bug CC-22842 as current error message is: "quantity => This value should be less than 2147483647." and not This value should be greater than 0.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":"21474836471"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be of type integer.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be less than 2147483647.
+
+
+Update_product_quntity_at_the_shopping_list_to_a_negative_number
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":"-2"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be of type integer.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... quantity => This value should be greater than 0.
+
+Update_product_in_the_shopping_list_withot_shopping_list_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_product_in_the_shopping_list_without_quantity_in_the_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"shopping-list-items","attributes":{}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+
+Update_product_in_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_product_at_the_shopping_list_with_empty_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"type":"","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_product_at_the_shopping_list_without_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ ... {"data":{"attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Remove_a_product_from_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Remove_a_product_from_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Remove_a_product_with_non_existing_id_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1504
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list item not found.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists//shopping-list-items/shoppingListItemId
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_item_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+#https://spryker.atlassian.net/browse/CC-16674
+
+Remove_a_concrete_product_from_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration_and_configurable_product
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":0,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"fake","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":-2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should not be blank.
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_aconfigurable_product_with_missing_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_aconfigurable_product_with_string_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"string","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":1,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":"True","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot
new file mode 100644
index 0000000..ce4d675
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot
@@ -0,0 +1,564 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue shopping-lists product bundle-products prices configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_one_more_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.concrete_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.product_1.concrete_sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_the_same_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_random_weight_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.random_weight.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete.random_weight.sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_bundle_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.concrete_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.product_1.concrete_sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+# need to find unavailable product
+
+Add_an_unavailable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.unavailable_products_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete.unavailable_products_sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists/${sharedShoppingListId}/shopping-list-items
+ ... {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be:
+ ... [data][attributes][sku]
+ ... ${concrete.available_product.with_stock.product_1.sku}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.concrete_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.concrete_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_bundle_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.product_1.concrete_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 3
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][type] shopping-list-items
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][id] ${shoppingListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${shoppingListItemId}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"20.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"20.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"01.01.2025\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_the_quantity_of_the_Configured_Product_so_Volume_price_is_applied
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":6,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 6
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][grossAmount] 165
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][netAmount] 150
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${shoppingListItemId1} ${shoppingListItemId2}
+ And Response body parameter should be in: [included][0][attributes][quantity] 2 1
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku} ${shoppingListItemId1} ${shoppingListItemId2}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][isComplete] True False
+ And Response body parameter should be in: [included][1][id] ${shoppingListItemId1} ${shoppingListItemId2} ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][attributes][quantity] 1 2
+ And Response body parameter should be in: [included][1][attributes][sku] ${shoppingListItemId1} ${shoppingListItemId2} ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete.available_product.with_stock.product_1.sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${shoppingListItemId2} ${shoppingListItemId1}
+ And Response body parameter should be in: [included][0][attributes][quantity] 2 1
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku} ${concrete.available_product.with_stock.product_1.sku}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] displayData {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] isComplete True
+ And Response body parameter should be in: [included][1][id] ${shoppingListItemId2} ${shoppingListItemId1}
+ And Response body parameter should be in: [included][1][attributes][quantity] 1 2
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku} ${concrete.available_product.with_stock.product_1.sku}
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete.available_product.with_stock.product_1.sku}
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete.available_product.with_stock.product_1.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot
new file mode 100644
index 0000000..1d9e23f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot
@@ -0,0 +1,280 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue shopping-lists customer-access customer-account-management acl
+
+
+*** Test Cases ***
+Create_a_shopping_list_with_empty_type
+ I send a POST request:
+ ... /shopping-lists
+ ... {"data":{"type":"","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... name => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_non_autorized_user
+ I send a POST request:
+ ... /shopping-lists
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Create_a_shopping_list_with_absent_type
+ I send a POST request: /shopping-lists {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_already_existing_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request:
+ ... /shopping-lists
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... Shopping list with given name already exists.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shopping_list_with_too_long_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... name => This value is too long. It should have 255 characters or less.
+
+Delete_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Delete_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a DELETE request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
+
+Delete_a_shopping_list_withouth_shopping_list_id
+ I send a DELETE request: /shopping-lists
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_for_the_customer_with_empty_attribute_section
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+Update_shopping_list_with_existing_name_of_another_available_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND Save value to a variable: [data][1][attributes][name] 2ndShoppingListName
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${2ndShoppingListName}"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... Shopping list with given name already exists.
+
+Update_shopping_list_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... name => This value should not be blank.
+
+Update_shopping_list_name_with_too_long_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... name => This value is too long. It should have 255 characters or less.
+
+Update_shopping_list_withouth_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_with_wrong_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_shopping_list_with_non_autorized_user
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Update_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_a_shopping_list_with_absent_type
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_shopping_list_with_invalid_type
+ I send a PATCH request:
+ ... /shopping-lists/shoppingListId
+ ... {"data":{"type":"shoppinglists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_shopping_list_with_non_autorized_user
+ I send a GET request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Get_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a GET request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot
new file mode 100644
index 0000000..77e9666
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot
@@ -0,0 +1,280 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue shopping-lists customer-access customer-account-management acl
+
+
+*** Test Cases ***
+Create_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request:
+ ... /shopping-lists
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListId
+ And Save value to a variable: [data][attributes][createdAt] createdAt
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be:
+ ... [data][attributes][owner]
+ ... ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a DELETE request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+
+Update_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name_with_includes
+ [Documentation] b2b2 - There is a bug CC-16543. Bug is resolved but it looks like we need integration to b2b public demoshop
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request:
+ ... /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ ... {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value:
+ ... [data][relationships][shopping-list-items][data]
+ ... [type]
+ ... shopping-list-items
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data][relationships][shopping-list-items][data]
+ ... [id]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [type]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [id]
+ ... str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_a_shopping_list_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND Save value to a variable: [data][attributes][createdAt] createdAt
+ ... AND Save value to a variable: [data][attributes][updatedAt] updatedAt
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be:
+ ... [data][attributes][owner]
+ ... ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}2"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId2
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... shopping-lists
+ And Each array element of array in response should contain nested property with datatype: [data] id str
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... [attributes][owner]
+ ... ${yves_user.first_name} ${yves_user.last_name}
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data]
+ ... [attributes][name]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data]
+ ... [attributes][createdAt]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data]
+ ... [attributes][updatedAt]
+ ... str
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId1}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I send a DELETE request: /shopping-lists/${shoppingListId2}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_shopping_lists_info_with_non_zero_quantity_of_number_of_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should NOT be: [data][0][attributes][numberOfItems] None
+
+Get_shopping_lists_info_for_user_with_zero_quantity_of_number_of_shopping_lists
+ [Setup] Run Keywords I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_single_shopping_list_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete.available_product.with_stock.product_1.sku}","quantity":3}}}
+ ... AND Response status code should be: 201
+ I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value:
+ ... [data][relationships][shopping-list-items][data]
+ ... [type]
+ ... shopping-list-items
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data][relationships][shopping-list-items][data]
+ ... [id]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [type]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [id]
+ ... str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... [relationships][shopping-list-items][data][0][type]
+ ... shopping-list-items
+ And Each array element of array in response should contain nested property with datatype:
+ ... [data]
+ ... [relationships][shopping-list-items][data][0][id]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [type]
+ ... str
+ And Each array element of array in response should contain nested property with datatype:
+ ... [included]
+ ... [id]
+ ... str
+ And Each array element of array in response should contain nested property with value:
+ ... [data]
+ ... type
+ ... shopping-lists
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][0][relationships] 0
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/negative.robot
new file mode 100644
index 0000000..932a0c7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/negative.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue
+
+
+*** Test Cases ***
+#GET requests
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+Get_health_check_with_disabled_services
+### Test works only if all services are disabled as default
+ When I send a GET request: /health-check
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 403
+ And Response body parameter should be:
+ ... [data][0][attributes][message]
+ ... HealthCheck endpoints are disabled for all applications.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_invalid_service_name
+ When I send a GET request: /health-check?services=sear
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_empty_service_name
+ When I send a GET request: /health-check?services=
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+#Get_health_check_with_non_existing_id
+### The bug https://spryker.atlassian.net/browse/CC-16492 related to the self link and required ID
+ #When I send a GET request: /health-check/1
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][type] health-check
+ #And Response body parameter should be: [data][id] None
+ #And Response body parameter should be: [data][attributes][status] healthy
+ #And Response body parameter should be: [data][attributes][statusCode] 200
+ #And Response body parameter should be: [data][attributes][message] None
+ #And Response body parameter should be: [data][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][attributes][healthCheckServiceResponses][1][name] storage
+ #And Response body parameter should be: [data][attributes][healthCheckServiceResponses][2][name] zed-request
+ #And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] status True
+ #And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] message None
+ ### Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/positive.robot
new file mode 100644
index 0000000..faa683d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/health_checks/positive.robot
@@ -0,0 +1,74 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue
+
+
+*** Test Cases ***
+# GET requests
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+# Get_health_check_with_all_enabled_services
+# When I send a GET request: /health-check
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 3
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][1][name] storage
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][2][name] zed-request
+# And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] status True
+# And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] message None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_search_service
+# When I send a GET request: /health-check?services=search
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_storage_service
+# When I send a GET request: /health-check?services=storage
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] storage
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_zed_request_service
+# When I send a GET request: /health-check?services=zed-request
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] zed-request
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..8dd7ad5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core
+
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response should return error code: 601
+ And Response should return error message: Store not found.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..76edc06
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/stores/positive.robot
@@ -0,0 +1,281 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core
+
+
+*** Test Cases ***
+Get_all_available_stores
+ [Tags] dms-off
+ [Documentation] works only for dms-off shop as in dms-on regions don't have timeZone and locale code
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] timeZone
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... defaultCurrency
+
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][currencies]
+ ... code
+ ... ${currency.eur.code}
+ ... ${currency.dollar.code}
+ ... ${currency.chf.code}
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][currencies]
+ ... name
+ ... ${currency.eur.name}
+ ... ${currency.dollar.name}
+ ... ${currency.chf.name}
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][currencies]
+ ... code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][currencies]
+ ... name
+
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][locales]
+ ... code
+ ... ${locale.DE.code}
+ ... ${locale.EN.code}
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][locales]
+ ... name
+ ... ${locale.DE.name}
+ ... ${locale.EN.name}
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][locales]
+ ... code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][locales]
+ ... name
+
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... iso2Code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... iso3Code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... name
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... postalCodeMandatory
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... postalCodeRegex
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... regions
+
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_all_available_stores_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes]
+ ... defaultCurrency
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][currencies]
+ ... name
+ ... ${currency.eur.name}
+ ... ${currency.dollar.name}
+ ... ${currency.chf.name}
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][currencies]
+ ... code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][currencies]
+ ... name
+
+ And Each array element of nested array should contain property with value in:
+ ... [data]
+ ... [attributes][locales]
+ ... name
+ ... ${locale.DE.name}
+ ... ${locale.EN.name}
+
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][locales]
+ ... name
+
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... iso2Code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... iso3Code
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... name
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... postalCodeMandatory
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... postalCodeRegex
+ And Each array element of array in response should contain nested property:
+ ... [data]
+ ... [attributes][countries]
+ ... regions
+
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ [Tags] dms-off
+ [Documentation] works only for dms-off shop as in dms-on regions don't have timeZone and locale code
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+
+ And Response body parameter should have datatype: [data][attributes][timeZone] str
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][currencies]
+ ... name
+ ... ${currency.eur.name}
+ ... ${currency.dollar.name}
+ ... ${currency.chf.name}
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][currencies]
+ ... code
+ ... ${currency.eur.code}
+ ... ${currency.dollar.code}
+ ... ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][locales]
+ ... code
+ ... ${locale.DE.code}
+ ... ${locale.EN.code}
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][locales]
+ ... name
+ ... ${locale.DE.name}
+ ... ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][locales] code
+
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property:
+ ... [data][attributes][countries]
+ ... postalCodeMandatory
+ And Each array element of array in response should contain property:
+ ... [data][attributes][countries]
+ ... postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+
+ And Response body has correct self link internal
+
+Get_store_by_id_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][currencies]
+ ... name
+ ... ${currency.eur.name}
+ ... ${currency.dollar.name}
+ ... ${currency.chf.name}
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][currencies]
+ ... code
+ ... ${currency.eur.code}
+ ... ${currency.dollar.code}
+ ... ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+
+ And Each array element of array in response should contain property with value in:
+ ... [data][attributes][locales]
+ ... name
+ ... ${locale.DE.name}
+ ... ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property:
+ ... [data][attributes][countries]
+ ... postalCodeMandatory
+ And Each array element of array in response should contain property:
+ ... [data][attributes][countries]
+ ... postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/negative.robot
new file mode 100644
index 0000000..f0b4227
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core
+
+
+*** Test Cases ***
+Get_url_collection_by_non_exist_url
+ When I send a GET request: /url-resolver?url=/non/exists/url
+ Then Response status code should be: 404
+ And Response should return error code: 2802
+ And Response should return error message: Url not found.
+
+Get_absent_url_collections
+ When I send a GET request: /url-resolver
+ Then Response status code should be: 422
+ And Response should return error code: 2801
+ And Response should return error message: Url request parameter is missing.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/positive.robot
new file mode 100644
index 0000000..611c48b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/utility_endpoints/url_resolver/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core
+
+
+*** Test Cases ***
+Get_url_collections_by_url_paramater
+ When I send a GET request: /url-resolver?url=${url_resolver.example}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.entity_type}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.entity_id}
+ And Each array element of array in response should contain nested property: [data] attributes entityType
+ And Each array element of array in response should contain nested property: [data] attributes entityId
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot
new file mode 100644
index 0000000..b6e4cb8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue measurement-units product
+
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_unit_id
+ When I send a GET request: /product-measurement-units/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3402
+ And Response should return error message: Product measurement unit not found.
+
+Get_a_measurement_unit_with_empty
+ When I send a GET request: /product-measurement-units
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3401
+ And Response should return error message: Product measurement unit code has not been specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot
new file mode 100644
index 0000000..b3941d0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue measurement-units product
+
+
+*** Test Cases ***
+Get_product_measurement_unit_by_id
+ When I send a GET request: /product-measurement-units/${measurement_unit.m}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${measurement_unit.m}
+ And Response body parameter should be: [data][type] product-measurement-units
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][defaultPrecision]
+ And Response body parameter should have datatype: [data][attributes][defaultPrecision] int
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/negative.robot b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/negative.robot
new file mode 100644
index 0000000..ce56e06
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/negative.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product measurement-units packaging-units
+
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_sku
+ When I send a GET request: /concrete-products/fake/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_abstract_sku
+ When I send a GET request: /concrete-products/${abstract.available_products.with_stock.sku}/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_empty_sku
+ When I send a GET request: /concrete-products//sales-units
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/positive.robot b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/positive.robot
new file mode 100644
index 0000000..0676d97
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/glue/weight_unit_endpoints/sales_units/positive.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue product measurement-units packaging-units
+
+
+*** Test Cases ***
+Get_sales_units_for_product_without_sales_units
+ When I send a GET request: /concrete-products/${concrete.available_product.with_stock.product_1.sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_sales_units
+ When I send a GET request: /concrete-products/${concrete.random_weight.sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${concrete.random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][precision] int
+ And Each array element of array in response should contain nested property with datatype in: [data] [attributes][conversion] int float
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDisplayed] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDefault] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][productMeasurementUnitCode] ${packaging_unit.m} ${packaging_unit.cm}
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_measurement_units_include
+ When I send a GET request: /concrete-products/${concrete.random_weight.sku}/sales-units?include=product-measurement-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${concrete.random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Response body has correct self link
+ And Each array element of array in response should contain a nested array of a certain size: [data] [relationships] 1
+ And Response should contain the array of a certain size: [included] ${concrete.random_weight.qty_of_units}
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include element has self link: product-measurement-units
diff --git a/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..6da845a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found
diff --git a/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..ca00fc3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2b/sapi/utility_endpoints/stores/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_all_availiable_stores
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/negative.robot
new file mode 100644
index 0000000..872757c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/negative.robot
@@ -0,0 +1,396 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_product_abstract_collection_with_invalid_query_parameter:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=test
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+
+Create_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH INVALID CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_correct_child_and_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}, {"fk_tax_set": 1, "attributes": "FOO1", "sku": "FOO1", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR1", "sku": "FOOBAR1"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ And Response body parameter should be: [data][0][sku] FOO1
+ And Response body parameter should be: [data][0][attributes] FOO1
+ ### GET PRODUCT ABSTRACT WITH CHILDREN ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] FOO1
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][id_product] ${id_product}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1310
+ And Response body parameter should be: [0][message] Incomplete Request - missing identifier for `robot-tests-product-abstracts0.robot-tests-products0`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1309
+ And Response body parameter should be: [0][message] Failed to persist the data for `robot-tests-product-abstracts0.robot-tests-products0.sku`. Please verify the provided data and try again. Entry is duplicated.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_country_collection_with_existing_child_entity
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_product_abstract_by_id_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST PRODUCT ABSTRACT ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_product_abstract_collection_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_price_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/positive.robot
new file mode 100644
index 0000000..ca3fe83
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/complex/positive.robot
@@ -0,0 +1,351 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+ Get_product_abstract_collection_with_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Delete dynamic entity configuration in Database: robot-tests-product-prices
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ Trigger p&s
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 215
+ And Response should contain the array of a certain size: [data][0] 8
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Each array element of array in response should contain property: [data] id_product_abstract
+ And Each array element of array in response should contain property: [data] sku
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] id_product
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] fk_product_abstract
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 215
+ And Response should contain the array of a certain size: [data][0] 8
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Get_product_abstract_with_childs_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 8
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response body parameter should be: [data][id_product_abstract] 130
+ And Response body parameter should be: [data][sku] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][1][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][2][fk_product_abstract] 130
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 8
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Create_and_update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Create_product_abstract_collection_with_two_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH TWO CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}], "robotTestsProductPrices": [{"fk_price_type": 1, "price": 0}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO2
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR2
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ When Save value to a variable: [data][0][robotTestsProductPrices][0][id_price_product] id_price_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][0][robotTestsProductPrices][0][fk_product_abstract] ${id_product_abstract}
+
+ [Teardown] Run Keywords Delete product_price by id_price_product in Database: ${id_price_product}
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Upsert_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract},"attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][new_to] None
+ And Response body parameter should be: [data][0][color_code] None
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_publish_complex_product_with_child_relations:
+ [Documentation] As the tech dept, we need to adjust this test to check in /catalog-search as well.
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-stock-products spy_stock_product 1 {"identifier":"id_stock_product","fields":[{"fieldName":"id_stock_product","fieldVisibleName":"id_stock_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"quantity","fieldVisibleName":"quantity","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_never_out_of_stock","fieldVisibleName":"is_never_out_of_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_stock","fieldVisibleName":"fk_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-localized-attributes spy_product_localized_attributes 1 {"identifier":"id_product_attributes","fields":[{"fieldName":"id_product_attributes","fieldVisibleName":"id_product_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-stores spy_product_abstract_store 1 {"identifier":"id_product_abstract_store","fields":[{"fieldName":"id_product_abstract_store","fieldVisibleName":"id_product_abstract_store","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relations spy_product_relation 1 {"identifier":"id_product_relation","fields":[{"fieldName":"id_product_relation","fieldVisibleName":"id_product_relation","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_relation_type","fieldVisibleName":"fk_product_relation_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_rebuild_scheduled","fieldVisibleName":"is_rebuild_scheduled","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"product_relation_key","fieldVisibleName":"product_relation_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"query_set_data","fieldVisibleName":"query_set_data","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relation-stores spy_product_relation_store 1 {"identifier":"id_product_relation_store","fields":[{"fieldName":"id_product_relation_store","fieldVisibleName":"id_product_relation_store","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_relation","fieldVisibleName":"fk_product_relation","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-products spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-stores spy_price_product_store 1 {"identifier":"id_price_product_store","fields":[{"fieldName":"id_price_product_store","fieldVisibleName":"id_price_product_store","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_currency","fieldVisibleName":"fk_currency","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_price_product","fieldVisibleName":"fk_price_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"gross_price","fieldVisibleName":"gross_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"net_price","fieldVisibleName":"net_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-defaults spy_price_product_default 1 {"identifier":"id_price_product_default","fields":[{"fieldName":"id_price_product_default","fieldVisibleName":"id_price_product_default","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_product_store","fieldVisibleName":"fk_price_product_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-label-product-abstracts spy_product_label_product_abstract 1 {"identifier":"id_product_label_product_abstract","fields":[{"fieldName":"id_product_label_product_abstract","fieldVisibleName":"id_product_label_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_label","fieldVisibleName":"fk_product_label","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-image-sets spy_product_image_set 1 {"identifier":"id_product_image_set","fields":[{"fieldName":"id_product_image_set","fieldVisibleName":"id_product_image_set","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-stores robotTestsProductAbstractStores fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-relations robotTestsProductRelations fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-relations robot-tests-product-relation-stores robotTestsProductRelationStores fk_product_relation id_product_relation
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-price-products robotTestsProductAbstractPriceProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-price-products robot-tests-price-product-stores robotTestsPriceProductStores fk_price_product id_price_product
+ Create dynamic entity configuration relation in Database: robot-tests-price-product-stores robot-tests-price-product-defaults robotTestsPriceProductStoreDefaults fk_price_product_store id_price_product_store
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-categories robotTestsProductAbstractCategories fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-label-product-abstracts robotTestsProductLabelProductAbstracts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-image-sets robotTestsProductImageSets fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-searches robotTestsProductSearch fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-stock-products robotTestsProductStocks fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-localized-attributes robotTestsProductLocalizedAttributes fk_product id_product
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH STOCK ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":2,"attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec","color_code":"#DC2E09","robotTestsProductAbstractProducts":[{"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1 test attributes","is_active":1,"is_quantity_splittable":1,"sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","robotTestsProductSearch":[{"fk_locale":66,"is_searchable":1}, {"fk_locale":46,"is_searchable":1}],"robotTestsProductStocks":[{"fk_stock":1,"is_never_out_of_stock":1,"quantity":10}],"robotTestsProductLocalizedAttributes":[{"fk_locale":66,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}],"robotTestsProductAbstractStores":[{"fk_store":1}],"robotTestsProductRelations":[{"fk_product_relation_type":1,"is_active":1,"is_rebuild_scheduled":1,"product_relation_key":"Prk-d04e93a4-29ea-4c48-96ab-e87416aefbec","query_set_data":"","robotTestsProductRelationStores":[{"fk_store":1}]}],"robotTestsProductAbstractPriceProducts":[{"fk_price_type":1,"price":1000,"robotTestsPriceProductStores":[{"fk_currency":93,"fk_store":1,"gross_price":9999,"net_price":8999,"robotTestsPriceProductStoreDefaults":[{}]}]}],"robotTestsProductAbstractCategories":[{"fk_category":5,"product_order":16}],"robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"},{"fk_locale":46,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"}],"robotTestsProductLabelProductAbstracts":[{"fk_product_label":1}],"robotTestsProductImageSets":[{"fk_locale":66,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}]}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Save value to a variable: [data][0][sku] abstract_sku
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][sku] concrete_sku
+ Trigger p&s
+ Trigger p&s
+ Trigger p&s
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /abstract-products/${abstract_sku}/abstract-product-availabilities
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] d04e93a4-29ea-4c48-96ab-e87416aefbec
+
+ I set Headers: Content-Type=application/vnd.api+json Accept=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /concrete-products/${concrete_sku}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ And Response body parameter should be: [data][attributes][sku] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-searches?filter[product-searches.fk_product]=${id_product}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][0][id_product_search] id_product_search_first
+ And Save value to a variable: [data][1][id_product_search] id_product_search_second
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-searches {"data": [{"id_product_search": ${id_product_search_first},"is_searchable": 0}, {"id_product_search": ${id_product_search_second},"is_searchable": 0}]}
+ Then Response status code should be: 200
+ Trigger p&s
+ Trigger p&s
+ [Teardown] Run Keywords Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductSearch
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductStocks
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductImageSets
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLabelProductAbstracts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractCategories
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStoreDefaults
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractPriceProducts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelationStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelations
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-image-sets
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-label-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-categories
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-defaults
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relation-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relations
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
+ ... AND Delete dynamic entity configuration in Database: robot-tests-stock-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/negative.robot
new file mode 100644
index 0000000..189c3a1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/negative.robot
@@ -0,0 +1,451 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_list_of_country_with_invalid_token
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID TOKEN ###
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_prefix
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE PREFIX ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity-invalid/robot-test-countries
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE NAME ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/invalid-resource
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/countries/9999999
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_body
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY BODY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_json
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY JSON ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {"data": []}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_valid_and_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}, {"iso2_code":"XX", "iso3_code":"XXX", "name":"Country XXX"}]}
+ Then Response status code should be: 201
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ And Response body parameter should contain: [data][0][iso2_code] XX
+ And Response body parameter should contain: [data][0][iso3_code] XXX
+ When Save value to a variable: [data][0][id_country] country_id
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID RESOURCE NAME ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/cnt {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 404
+ And Response body parameter should contain: [0][message] Not found
+ And Response body parameter should be: [0][code] 007
+ And Response body parameter should contain: [0][status] 404
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_field_value
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID FIELD VALUE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"X","iso3_code":"XXXX","name":""}]}
+ Then Response status code should be: 400
+ And Response should contain the array of a certain size: $ 3
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should contain: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries0` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should contain: [1][status] 400
+ And Response body parameter should contain: [2][message] Invalid data value `robot-test-countries0` for field: `name`.
+ And Response body parameter should be: [2][code] 1306
+ And Response body parameter should contain: [2][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: X
+
+Create_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url", "fk_locale": 46}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] XXA
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] XXB
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XXXX"}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_collection_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY COLLECTION WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XXXX"},{"id_country":${xxb_country_id},"iso3_code":"XXXXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries1` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should be: [1][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field_type
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID FILELD TYPE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name": "FOO", "iso2_code":1234, "iso3_code": 1234}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data type `robot-test-countries0` for field `iso2_code`
+ And Response body parameter should be: [0][code] 1305
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Upsert_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### UDATE WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/1000 {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Entity `robot-test-countries0.id_country: 1000` not found by identifier, and new identifier can not be persisted. Please update the request.
+ And Response body parameter should be: [0][code] 1308
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Delete_country_by_id_is_deletable_false:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": false,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_is_deletable_null:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": null,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_without_is_deletable:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/positive.robot
new file mode 100644
index 0000000..5793370
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/dynamic_entity/positive.robot
@@ -0,0 +1,579 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/api_dynamic_entity_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_country_collection
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 6
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] iso3_code ZMB
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_Collection_with_filter_first_item
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER FIRST ITEM ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=AC
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=UA
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_multiple_filter_fields
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}&filter[countries.postal_code_mandatory]=1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter_in_condition
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code AE
+ And Array in response should contain property with value: [data] iso3_code ARE
+ And Array in response should contain property with value: [data] name United Arab Emirates
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_invalid_multiple_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"], "not in": ["AT"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=234&page[limit]=2
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property: [data] iso2_code
+ And Each array element of array in response should contain property: [data] iso3_code
+ And Each array element of array in response should contain property: [data] name
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations_out_of_items
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS OUT OF ITEMS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=500&page[limit]=10
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+
+Get_country_collection_with_short_configuration
+ ### SETUP DYNAMIC ENTITY CONFIGURATION WITH LESS NUMBER OF FIELDS ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH SHORT CONFIGURATION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 3
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_by_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request with data: /token 'grantType=password&username=admin@spryker.com&password=change123'
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+ When Save value to a variable: [access_token] token
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should not be EMPTY: [data][iso2_code]
+ And Response body parameter should not be EMPTY: [data][iso3_code]
+ And Response body parameter should not be EMPTY: [data][name]
+ And Response body parameter should not be EMPTY: [data][postal_code_mandatory]
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_and_update_country:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XM
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XM","iso3_code":"XXM","name":"POST XM"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XM
+ And Response body parameter should be: [data][0][iso3_code] XXM
+ And Response body parameter should be: [data][0][name] POST XM
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ ### UPDATE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ ### UPDATE ONE FIELD OF COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name":"Test Country"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Test Country
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Test Country
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XM
+
+Create_and_update_url:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST URL AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: /test-url/123
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"/test-url/123", "fk_locale": 46}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][url] /test-url/123
+ And Response body parameter should be: [data][0][fk_locale] 46
+ When Save value to a variable: [data][0][id_url] id_url
+ ### UPDATE URL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls/${id_url} {"data":{"url":"/test-url-test/42"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ And Response body parameter should be: [data][id_url] ${id_url}
+ ### GET URL AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-urls/${id_url}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: /test-url-test/42
+
+Create_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Create_country_collection_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Upsert_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ Delete country by iso2_code in Database: XL
+ Delete country by iso2_code in Database: XS
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XAA","name":"PUT XAA"},{"iso2_code":"XB","iso3_code":"XBB","name":"PUT XBB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] PUT XAA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] PUT XBB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ When Save value to a variable: [data][0][id_country] xaa_country_id
+ When Save value to a variable: [data][1][id_country] xbb_country_id
+
+ ## UPSERT ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ ### PARTIAL UPDATE ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXL"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Country XXL
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXL
+ ### UPSERT COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xaa_country_id},"iso2_code":"XL","iso3_code":"XXL","name":"XXL"},{"id_country":${xbb_country_id},"iso2_code":"XS","iso3_code":"XXS","name":"XXS"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XL
+ And Response body parameter should be: [data][0][iso3_code] XXL
+ And Response body parameter should be: [data][0][name] XXL
+ And Response body parameter should be: [data][0][id_country] ${xaa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XS
+ And Response body parameter should be: [data][1][iso3_code] XXS
+ And Response body parameter should be: [data][1][name] XXS
+ And Response body parameter should be: [data][1][id_country] ${xbb_country_id}
+ ### GET COUNTRIES AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XL
+ And Response body parameter should be: [data][iso3_code] XXL
+ And Response body parameter should be: [data][name] XXL
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xbb_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XS
+ And Response body parameter should be: [data][iso3_code] XXS
+ And Response body parameter should be: [data][name] XXS
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XL
+ ... AND Delete country by iso2_code in Database: XS
+
+Delete_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_country_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][0][iso2_code] XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_id
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] ${xxa_iso2_code}
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `robot-test-countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Authorization_by_x_api_key
+ [Documentation] data excahnge api should support 2 autorization options: by x-api-key and by backoffice user token.
+ [Setup] Create api key in db
+ When I set Headers: x-api-key=${dummy_api_key}
+ And I send a GET request: /dynamic-entity/categories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ [Teardown] Delete api key from db
+
+Availability_recalculation_after_stock_update
+ [Documentation] checks that product availability is recalculated after stock update via data exchange api
+ [Setup] Find first available product via data exchange api
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/stock-products/${index} {"data":{"is_never_out_of_stock":false,"quantity":0}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][is_never_out_of_stock] False
+ And Response body parameter should be: [data][quantity] 0
+ Trigger p&s
+ And Product availability status should be changed on: is_available=False
+ [Teardown] Run Keywords Remove Tags *
+ ... AND Set Tags bapi
+ ... AND Restore product initial stock via data exchange api:
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot
new file mode 100644
index 0000000..b6736cf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot
@@ -0,0 +1,127 @@
+
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Retrieve_push_notification_providers_without_authorization
+ When I set Headers: Content-Type=application/vnd.api+json
+ And I send a GET request: /push-notification-providers
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_push_notification_providers_with_incorrect_token
+ When I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer incorrect_token
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Retrieve_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a GET request: /push-notification-providers/non-existent-id
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+Create_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+
+Create_push_notification_provider_without_authorization
+ I set Headers: Content-Type=application/vnd.api+json
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Create_push_notification_provider_with_invalid_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "invalid-type","attributes": {"name": "Invalid Type Push Notification Provider"}}}
+ Then Response status code should be: 400
+ And Response should return error message: Validation issues during the creation
+
+Create_two_push_notification_providers_with_same_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_256_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNamesadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5007
+ And Response should return error message: A push notification provider name must have length from 1 to 255 characters.
+
+Update_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider_with_incorrect_auth
+ [Setup] Run Keywords I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer invalid
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider Updated"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a PATCH request: /push-notification-providers/non-existent-uuid {"data": {"type": "push-notification-providers","attributes": {"name": "Non-Existent Push Notification Provider Updated"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+ Update_push_notification_provider_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id_2} {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Delete_push_notification_provider_with_not_exist_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ Then I send a DELETE request: /push-notification-providers/invalid
+ Then Response status code should be: 404
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot
new file mode 100644
index 0000000..3f3d213
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot
@@ -0,0 +1,135 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ And Response body has correct self link for created entity: ${push_notification_provider_id}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_255_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][attributes][name] testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider Updated ${random}"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider Updated ${random}
+ And Response body has correct self link internal
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Retrieve_push_notification_providers
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 200
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should be: [data][1][type] push-notification-providers
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][uuid]
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_pagination
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ # And I send a DELETE request: /push-notification-providers/${push_notification_provider_uuid}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification1${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification2${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?page[offset]=1&page[limit]=1
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should be: [data][0][attributes][name] My-Push-Notification1${random}
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_sorting
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "A-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "B-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?sort=-name
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][name] web-push-php
+ And Response body parameter should be: [data][1][attributes][name] B-My-Push-Notification
+ And Response body parameter should be: [data][2][attributes][name] A-My-Push-Notification
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_by_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ When I send a GET request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Delete_push_notification_provider_while_push_notification_subscribtion_exists
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses.name} ${True} ${warehouses.uuid}
+ ... AND Assign user to Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ I get access token by user credentials: admin@spryker.com
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # create a provider for push notification
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Save value to a variable: [data][attributes][name] push_notification_provider_name
+ # create a subscription
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_provider_name}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses.uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ Then I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 400
+ And Response should return error code: 5004
+ And Response should return error message: Unable to delete push notification provider while push notification subscription exists.
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ ... AND Delete warehouse in DB: ${warehouses.uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
new file mode 100644
index 0000000..1cceea2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_incorrect_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses.name} ${True} ${warehouses.uuid}
+ ... AND Assign user to Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ I get access token by user credentials: admin@spryker.com
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses.uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"DU_AE"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Provided locale not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ ... AND Delete warehouse in DB: ${warehouses.uuid}
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
new file mode 100644
index 0000000..b253fc2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_correct_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses.name} ${True} ${warehouses.uuid}
+ ... AND Assign user to Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ I get access token by user credentials: admin@spryker.com
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses.uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] ${locale.DE.name}
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses.uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ ... AND Delete warehouse in DB: ${warehouses.uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+
+Creates_push_notification_subscription_without_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses.name} ${True} ${warehouses.uuid}
+ ... AND Assign user to Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ I get access token by user credentials: admin@spryker.com
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses.uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"}}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] None
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses.uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: admin@spryker.com ${warehouses.uuid}
+ ... AND Delete warehouse in DB: ${warehouses.uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/negative.robot
new file mode 100644
index 0000000..696e29f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/negative.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+New_warehouse_token_without_autorization
+ [Tags] skip-due-to-issue
+ [Documentation] https://spryker.atlassian.net/browse/FRW-2142
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Autorization is required.
+
+New_warehouse_token_with_invalid_token
+ [Tags] skip-due-to-issue
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1728
+ When I set Headers: Authorization=fake_token Content-Type=application/x-www-form-urlencoded
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+New_warehouse_token_for_admin_user_who_is_not_a_WH_user
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${admin_not_warehouse_user.email}","password": "${admin_not_warehouse_user.password}"}
+ Then Response status code should be: 200
+ And Save value to a variable: [access_token] bapi_token
+ When I set Headers: Authorization=Bearer ${bapi_token}
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [0][code] 5101
+ And Response body parameter should be: [0][message] Operation is forbidden.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/positive.robot
new file mode 100644
index 0000000..59ea6a8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_tokens/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Generate_new_user_token
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+# Generate_new_warehouse_token
+# # needs to be completed as werahouse token can be created only for user who is a warehouse user with assigned and ACTIVE warehouse.
+# # Making user a warehouse user is available now only via Back office frontend.
+# When I set Headers: Content-Type=application/x-www-form-urlencoded
+# When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+# Then Response status code should be: 200
+# And Save value to a variable: [access_token] bapi_token
+# When I set Headers: Authorization=${bapi_token} Content-Type=application/x-www-form-urlencoded
+# And I send a POST request: /warehouse-tokens {}
+# Then Response status code should be: 201
+# And Response body parameter should be: [data][type] warehouse-tokens
+# And Response body parameter should be: [data][attributes] Bearer
+# And Response body parameter should be greater than: [data][attributes][expiresin] 0
+# And Response body parameter should be less than: [data][attributes][expiresin] 30000
+# And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+# And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+# And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+# And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/negative.robot b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/negative.robot
new file mode 100644
index 0000000..dcee7e5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/negative.robot
@@ -0,0 +1,202 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Create_warehouse_user_assignment_with_invalid_token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 401
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Create_warehouse_user_assignment_without_token
+ And I set Headers: Content-Type=${default_header_content_type}
+ And Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Create_warehouse_user_assignment_as_warehouse_user_for_other_user
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 404
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${user_uuid} 0
+
+Create_warehouse_user_assignment_with_invalid_body
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "test","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Create_warehouse_user_assignment_with_empty_body
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {}}
+ Then Response status code should be: 400
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Create_warehouse_user_assignment_with_incorrect_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "invalid", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Create_warehouse_user_assignment_with_duplicate_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5206
+ And Response should return error message: Warehouse user assignment already exists.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_warehouse_user_assignments_by_UUID_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 403
+ And Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_user_assignments_by_UUID_with_invalid_token
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ When I get access token by user credentials: invalid
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_user_assignments_by_invalid_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ Then I send a GET request: /warehouse-user-assignments/invalid
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_user_assignments_list_with_invalid_token
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_user_assignments_list_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 403
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Update_warehouse_user_assignment_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Update_warehouse_user_assignment_with_invalid_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Update_warehouse_user_assignment_without_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Then I send a PATCH request: /warehouse-user-assignments/invalid {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Delete_warehouse_user_assignment_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 400
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+ Delete_warehouse_user_assignment_with_invalid_token
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ And Create_warehouse_user_assignment: ${warehouse_uuid} ${fk_warehouse_spryker} ${admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse_uuid} ${admin_user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse_uuid} ${admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/positive.robot b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/positive.robot
new file mode 100644
index 0000000..52055c7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/bapi/warehouse_user_assignments/positive.robot
@@ -0,0 +1,268 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Assign_user_to_warehouse
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response reason should be: Created
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link for created entity: ${warehouse_assignment_id}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Assign_user_to_warehouse_with_include
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response body parameter should not be EMPTY: [data][relationships][users][data][0][id]
+ And Each array in response should contain property with NOT EMPTY value: [data][relationships][users][data] id
+ And Each array element of array in response should contain property with value: [data][relationships][users][data] type users
+ And Each array in response should contain property with NOT EMPTY value: [included] id
+ And Each array element of array in response should contain property with value: [included] type users
+ And Response body parameter should be: [included][0][attributes][username] ${user_name_1}
+ And Response body parameter should be: [included][0][attributes][firstName] ${user_first_name_1}
+ And Response body parameter should be: [included][0][attributes][lastName] ${user_last_name_1}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_warehouse_user_assignments_by_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Get_warehouse_user_assignments_list
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ # assign several warehouses to one user [only one warehouse active]
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should be in: [data][0][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be in: [data][1][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][1][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${admin_user_uuid}
+ And Response body parameter should be: [data][1][attributes][userUuid] ${admin_user_uuid}
+ And Response body parameter should be in: [data][0][attributes][isActive] False True
+ And Response body parameter should be in: [data][1][attributes][isActive] False True
+ And Response body parameter should be in: [data][0][attributes][warehouse][name] ${warehouse_name} ${video_king_warehouse_name}
+ And Response body parameter should be in: [data][1][attributes][warehouse][name] ${warehouse_name} ${video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ And Response body parameter should be: [data][1][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_assignment_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 1
+ # assign several users to one warehouse
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.uuid]=${warehouse_assignment_id_1}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${de_admin_user_uuid}","warehouse" :{"uuid": "${video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.warehouseUuid]=${video_king_warehouse_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${de_admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_user_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.userUuid]=${admin_user_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_isActive
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${de_admin_user_uuid}","warehouse" :{"uuid": "${video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.isActive]=true
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${de_admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${de_admin_user_uuid} 0
+
+Update_warehouse_user_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"false"}}}
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+ Create_warehouse_user_assignment_with_multiple_active_assignments
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] True
+ # when we creating second active user warehouse assignment for one user,the existing one assignment deactivated
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
+
+Update_one_of_already exist_warehouse_user_assignment_with_two_assignments_to active
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${admin_user_uuid}","warehouse" :{"uuid": "${video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id_1} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${admin_user_uuid} 0
diff --git a/atest/testdata/performance/tests/api/b2c/dynamic_store/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/b2c/dynamic_store/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..bce095d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/dynamic_store/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,27 @@
+# *** Settings ***
+# Resource ../../../../../../resources/common/common_api.robot
+# Suite Setup API_suite_setup
+# Test Setup API_test_setup
+# Test Tags glue
+
+
+# *** Test Cases ***
+# ENABLER
+# API_test_setup
+
+
+# # SEARCH PARAMETERS #
+
+
+# Search_by_abstract_sku_per_store
+# [Tags] dms-on
+# When I set Headers: store=DE
+# Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+# And Response status code should be: 200
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] ${abstract_available_product_with_stock.price_de}
+# When I set Headers: store=AT
+# Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+# And Response status code should be: 200
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] ${abstract_available_product_with_stock.price_at}
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
new file mode 100644
index 0000000..f63d154
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Get_alternative_abstract_with_nonexistant_SKU
+ When I send a GET request: /concrete-products/fake/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_with_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_without_SKU
+ When I send a GET request: /concrete-products//abstract-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
new file mode 100644
index 0000000..5971a55
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
@@ -0,0 +1,48 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Product_has_abstract_alternative
+ When I send a GET request: /concrete-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body parameter should have datatype: [data][0][attributes][name] str
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_product_with_alternative.sku}
+ And Response body has correct self link
+
+
+Product_has_abstract_alternative_with_includes
+ When I send a GET request: /concrete-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-alternative-products?include=abstract-product-image-sets,abstract-product-availabilities,abstract-product-prices,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body has correct self link
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: abstract-product-prices
+
+Product_has_no_abstract_alternative
+ When I send a GET request: /concrete-products/${bundled.product_1.concrete_sku}/abstract-alternative-products
+ Then Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ And Response reason should be: OK
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
new file mode 100644
index 0000000..6ff5ba2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management
+
+*** Test Cases ***
+Get_abstract_availability_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
new file mode 100644
index 0000000..a75b500
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
@@ -0,0 +1,64 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management
+
+*** Test Cases ***
+Product_is_available_with_stock_and_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_with_stock
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+# No demo data for B2C BUG CC-16485
+# Bug is resolved and unavailable product SKU is updated in test data
+Product_is_unavailable
+ When I send a GET request: /abstract-products/${product_availability.abstract_unavailable_product}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_unavailable_product}
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_available_with_3_concrete_stocks_combined
+ #checks that stock of all 3 concretes as aggregated in response
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
new file mode 100644
index 0000000..8eaad91
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_image_sets_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
new file mode 100644
index 0000000..c48a920
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management
+
+*** Test Cases ***
+Abstract_image_sets_with_1_concrete
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
+
+Abstract_image_sets_with_3_concretes
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${multivariant.abstract_product.concretes_3}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
new file mode 100644
index 0000000..828da10
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_prices_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
new file mode 100644
index 0000000..2d8d009
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
@@ -0,0 +1,86 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Abstract_prices_default_only
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default.price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default.price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Abstract_prices_default_only_CHF
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}/abstract-product-prices?currency=CHF&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default.price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default.price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Abstract_volume_prices
+ When I send a GET request: /abstract-products/${abstract_product.volume_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product.volume_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default.price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default.price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][grossAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][netAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][quantity] 1
+ And Response body has correct self link
+
+Abstract_prices_original_price
+ When I send a GET request: /abstract-products/${abstract_product.original_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product.original_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default.price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default.price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than: [data][0][attributes][prices][1][grossAmount] ${default.price}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.code}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.name}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.symbol}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${array}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/negative.robot
new file mode 100644
index 0000000..a1ffa85
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_product_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_by_fake_SKU
+ When I send a GET request: /abstract-products/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_with_missing_SKU
+ When I send a GET request: /abstract-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/positive.robot
new file mode 100644
index 0000000..f46ad2c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/abstract_product_endpoints/abstract_products/positive.robot
@@ -0,0 +1,155 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product tax product-labels product-options inventory-management
+
+*** Test Cases ***
+Abstract_product_with_one_concrete
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 1
+ And Response body parameter should contain: [data][attributes][superAttributesDefinition] ${abstract_available_product_with_stock.superattribute}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_3_concrete3
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be: [data][attributes][sku] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${multivariant.abstract_product.concretes_name_3}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 4
+ And Response body parameter should contain: [data][attributes][superAttributes] ${multivariant.abstract_product.concretes_superattribute_3}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_abstract_includes_for_availability_images_taxes_categories_and_prices
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=abstract-product-availabilities,abstract-product-image-sets,product-tax-sets,category-nodes,abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][abstract-product-prices][data] 0
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: abstract-product-prices
+
+
+Abstract_product_with_abstract_includes_for_labels
+ [Setup] Trigger product labels update
+ When I send a GET request: /abstract-products/${abstract_product.label.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.label.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.label.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.label.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-labels][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+
+Abstract_product_with_abstract_includes_for_reviews
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.with_reviews.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.with_reviews.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.with_reviews.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-reviews][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-reviews
+ And Response include element has self link: product-reviews
+
+Abstract_product_with_abstract_includes_for_options
+ When I send a GET request: /abstract-products/${abstract_product.with_options.sku}?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.with_options.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-options][data] 0
+ And Response should contain the array larger than a certain size: [included] 1
+ And Response include should contain certain entity type: product-options
+ And Response include element has self link: product-options
+
+Abstract_product_with_3_concrete_and_concrete_nested_includes
+ When I send a GET request: /abstract-products/${multivariant.abstract_product.concretes_3}?include=concrete-products,concrete-product-prices,concrete-product-image-sets,concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be: [data][attributes][sku] ${multivariant.abstract_product.concretes_3}
+ And Response body parameter should be: [data][attributes][name] ${multivariant.abstract_product.concretes_name_3}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 4
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include element has self link: concrete-products
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+
+Abstract_product_in_different_locales_languages
+ When I set Headers: Accept-Language=de-DE
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_de}
+ When I set Headers: Accept-Language=en-US
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_en}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/negative.robot
new file mode 100644
index 0000000..bec9234
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_access_token_with_invalid_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":"fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_access_token_with_invalid_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"fake@spryker.com","password":"${yves_user.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_access_token_with_empty_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+
+Get_access_token_with_empty_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: username => This value should not be blank.
+
+Get_access_token_with_invalid_type
+ When I send a POST request: /access-tokens {"data":{"type":"access","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_access_token_with_empty_type
+ When I send a POST request: /access-tokens {"data":{"type":"","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/positive.robot
new file mode 100644
index 0000000..cf9128f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/access_tokens/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_access_token_for_customer
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/negative.robot
new file mode 100644
index 0000000..15d5f4b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/negative.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+#######POST#######
+Refresh_token_with_access_token
+ [Setup] I get access token for the customer: ${yves_user.email}
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_invalid_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "faketoken"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_empty_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": ""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: refreshToken => This value should not be blank.
+
+Refresh_token_with_invalid_type
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "access-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Refresh_token_with_deleted_refresh_token
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ ... AND I set Headers: Authorization=Bearer ${access_token}
+ ... AND I send a DELETE request: /refresh-tokens/${refresh_token}
+ ... AND Response status code should be: 204
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Failed to refresh token.
+
+#######DELETE#######
+# Spryker is designed so removing non-existent refresh token will return 204 for security reasons
+Delete_refresh_token_with_invalid_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /refresh-tokens/faketoken
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_refresh_token_with_missing_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_refresh_token_with_no_access_token
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Spryker is designed so that deleting will return 204, but the token will not be removed and can be used (done for security reasons)
+Delete_refresh_token_for_another_user
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Authorization=Bearer ${access_token}
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/positive.robot
new file mode 100644
index 0000000..3516eda
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/refresh_tokens/positive.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Refresh_access_token_for_customer
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Save value to a variable: [data][attributes][accessToken] refreshed_access_token
+ And Response body has correct self link internal
+ When I set Headers: Authorization=Bearer ${refreshed_access_token}
+ And I send a GET request: /customers
+ Then Response status code should be: 200
+
+Delete_refresh_token_for_customer
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I set Headers: Authorization=Bearer ${access_token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/negative.robot
new file mode 100644
index 0000000..9991bcf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/negative.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer_with_invalid_client_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "invalid_client_type","username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_missing_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_invalid_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "wrong_password"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_for_customer_with_invalid_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "fake@spryker.com","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","password": "${yves_user.password}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+
+Get_token_using_refresh_token_for_customer_with_missing_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_client_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "invalid_client_type","refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_missing_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "invalid_refresh_token"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The refresh token is invalid.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/positive.robot
new file mode 100644
index 0000000..5926b5e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/access_token_endpoints/token/positive.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer
+ I set Headers: Content-Type=${urlencoded_header_content_type}
+ I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ Response status code should be: 200
+ Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+
+Get_token_using_refresh_token_for_customer
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "${refresh_token}"}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/negative.robot
new file mode 100644
index 0000000..91918df
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/negative.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_access_token_by_empty_email_and_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_with_blank_spaces
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username":" " ,"password":" "}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_valid_email_and_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_empty_email_and_valid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_wrong_email_format
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "abc","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_non_agent.email_and_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_invalid_email_and_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "spryker1232@gmail.com","password": "1234"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_invalid_email_and_valid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "spryker1232@gmail.com","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_vaild_email_and_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "12345"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_access_token_by_invalid_data_type
+ When I send a POST request: /agent-access-tokens {"data": {"type": "token","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/positive.robot
new file mode 100644
index 0000000..132edc4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_access_tokens/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_access_tokens
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] agent-access-tokens
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
new file mode 100644
index 0000000..76c3ae6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
@@ -0,0 +1,73 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_cannot_impersonate_customer_with_no_agent_token
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_wrong_token_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_invalid_token
+ [Setup] I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer fake
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Agent_cannot_impersonate_customer_with_wrong_type
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-token","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Agent_cannot_impersonate_customer_with_invalid_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_empty_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_missing_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
new file mode 100644
index 0000000..c9aeae8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_customer_impersonation_token
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-customer-impersonation-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/negative.robot
new file mode 100644
index 0000000..e2c7d2e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/negative.robot
@@ -0,0 +1,26 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Not_agent_can't_get_search_for_customers
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+
+Agent_can't_get_search_for_customers_without_token
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/positive.robot
new file mode 100644
index 0000000..455030f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/agent_endpoints/agent_customer_search/positive.robot
@@ -0,0 +1,149 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist customer-account-management
+
+*** Test Cases ***
+Agent_can_get_search_for_customers_without_search_parameters
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 10
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_email
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.email}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--21
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] sonia@spryker.com
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Sonia
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Wagner
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_first_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_second_user.first_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--4
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] bill.martin@spryker.co
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Bill
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Martin
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_last_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_second_user.last_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--4
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] bill.martin@spryker.co
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Bill
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Martin
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_with_changed_page_limit
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=0&page[limit]=20
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 20
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+
+Agent_can_get_search_for_customers_by_substring
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=mar
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 2
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] DE--2
+ And Response body parameter should be: [data][0][attributes][customers][0][email] maria.williams@spryker.com
+ And Response body parameter should be: [data][0][attributes][customers][1][customerReference] DE--4
+ And Response body parameter should be: [data][0][attributes][customers][1][email] bill.martin@spryker.com
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_incorrect_keyword
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=qqqq
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/negative.robot
new file mode 100644
index 0000000..b30f538
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/negative.robot
@@ -0,0 +1,137 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_without_customerId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers//availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 4606
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_with_invalid_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=325tr
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Authorization=
+ ... AND I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_without_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+
+
+#POST requests
+Subscribe_to_availability_notifications_with_empty_type
+ When I send a POST request: /availability-notifications {"data": {"type": "","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Subscribe_to_availability_notifications_without_type
+ When I send a POST request: /availability-notifications {"data": {"attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Subscribe_to_availability_notifications_with_invalid_sku
+#This test fails due to the bug https://spryker.atlassian.net/browse/CC-15970
+# Bug is fixed and resolved
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "fake","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${404}
+ And Response reason should be: Not Found
+ And Each array element of array in response should contain property with value: [errors] code 4601
+ And Each array element of array in response should contain property with value: [errors] status ${404}
+ And Array in response should contain property with value: [errors] detail Product not found.
+
+Subscribe_to_availability_notifications_with_invalid_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "gmail"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail email => This value is not a valid email address.
+
+Subscribe_to_availability_notifications_with_empty_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "","email": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+
+Subscribe_to_availability_notifications_without_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+
+Subscribe_to_availability_notifications_with_existing_subscription
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4602
+ And Response should return error message: Subscription already exists.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+
+
+#DELETE requests
+Delete_availability_notifications_with_invalid_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/7fc6ebf
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4603
+ And Response should return error message: "Subscription doesnt exist."
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Delete_availability_notifications_without_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/positive.robot
new file mode 100644
index 0000000..7b71d69
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/availability_notifications/positive.robot
@@ -0,0 +1,83 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_empty_list_of_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+
+
+#POST requests
+Subscribe_to_availability_notifications_for_customer
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+# bug CC-16977
+Subscribe_to_availability_notifications_with_non_existing_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "test1234546@gmail.com"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] test1234546@gmail.com
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+
+
+#DELETE requests
+Delete_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/${availability_notification_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/negative.robot
new file mode 100644
index 0000000..6641894
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+*** Test Cases ***
+Retrieves_my_availability_notifications_without_auth_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_my_availability_notifications_with_invalid_auth_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/positive.robot
new file mode 100644
index 0000000..2017457
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/availability_endpoints/my_availability_notifications/positive.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management
+
+*** Test Cases ***
+Get_my_availability_notifications
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Save value to a variable: [data][id] availabilityNotificationId
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availabilityNotificationId}
+ And Response body parameter should be in: [data][0][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] localeName
+ And Each array element of array in response should contain nested property: [data] [attributes] email
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availabilityNotificationId}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/negative.robot
new file mode 100644
index 0000000..fe38311
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_bundled_products_with_nonexisting_concrete_sku
+ [Documentation] bug:https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/fake/bundled-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_bundled_products_with_invalid_concrete_sku
+ [Documentation] bug:https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/:sku/bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_bundled_products_with_missing_concrete_sku
+ When I send a GET request: /concrete-products//bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/positive.robot
new file mode 100644
index 0000000..6c91128
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/bundle_endpoints/bundled_products/positive.robot
@@ -0,0 +1,86 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_concrete_bundled_products_inside_concrete_bundle
+ When I send a GET request: /concrete-products/${bundle_product.concrete_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Response body parameter should be in: [data][0][attributes][sku] ${bundled.product_1.concrete_sku} ${bundled.product_2.concrete_sku} ${bundled.product_3.concrete_sku}
+ And Response body parameter should be in: [data][1][attributes][sku] ${bundled.product_2.concrete_sku} ${bundled.product_1.concrete_sku} ${bundled.product_3.concrete_sku}
+ And Response body parameter should be in: [data][2][attributes][sku] ${bundled.product_3.concrete_sku} ${bundled.product_1.concrete_sku} ${bundled.product_2.concrete_sku}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][quantity] ${products_in_bundle.qty_of_each_product}
+ And Response body has correct self link
+
+Get_concrete_bundled_products_inside_concrete_bundle_with_included_concretes
+ When I send a GET request: /concrete-products/${bundle_product.concrete_sku}/bundled-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property with value: [data] [relationships][concrete-products][data][0][type] concrete-products
+ And Response should contain the array of a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+
+Get_concrete_bundle_product_with_bundled_products_include
+ When I send a GET request: /concrete-products/${bundle_product.concrete_sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data][relationships][bundled-products][data] type bundled-products
+ And Response should contain the array larger than a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_abstract_bundle_product_with_bundled_products_include
+ When I send a GET request: /abstract-products/${bundle_product.abstract_sku}?include=bundled-products,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${bundle_product.abstract_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.abstract_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body parameter should be: [data][attributes][attributeMap][product_concrete_ids] ${bundle_product.concrete_sku}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 1
+ And Response body parameter should be: [data][relationships][concrete-products][data][0][id] ${bundle_product.concrete_sku}
+ And Response should contain the array larger than a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_concrete_bundled_products_for_nonbundle_product
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/negative.robot
new file mode 100644
index 0000000..52bdaf8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/negative.robot
@@ -0,0 +1,242 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core
+
+*** Test Cases ***
+Get_cart_by_cart_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_cart_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/12345678
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_cart_by_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Get_cart_by_customer_id_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=234567thgf
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_customer_id_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ When I send a GET request: /customers/user-01/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ When I send a GET request: /customers//carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Create_cart_with_invalid_access_token
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_when_cart_already_exists
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Customer already has a cart.
+
+#PATCH requests
+Update_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=wrong_tag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Update_cart_without_access_token
+ [Setup] I set Headers: Authorization= If-Match=wrong_tag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Update_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/8567km {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+
+Update_cart_without_cart_id
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=wrong_tag
+ When I send a PATCH request: /carts/ {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_cart_from_another_customer_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_id
+ ... AND Get ETag header value from cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_cart_with_invalid_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=${token} If-Match="3278654tv3"
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+
+Update_cart_without_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 428
+ And Response reason should be: Precondition Required
+ And Response should return error message: If-Match header is missing.
+ And Response should return error code: 005
+
+Update_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "car","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Update_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Update_cart_with_invalid_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${ETag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "DEK"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+
+Delete_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart could not be deleted.
+ And Response should return error code: 105
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/positive.robot
new file mode 100644
index 0000000..1cdfefc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/carts/positive.robot
@@ -0,0 +1,265 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax promotions-discounts spryker-core customer-access multiple-carts
+
+*** Test Cases ***
+#GET requests
+
+Get_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a GET request: /carts/${cart_id}
+ Then Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+
+Get_cart_without_cart_id
+# Spryker is designed so that we can get all carts same as for /customers/{customerId}/carts request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a GET request: /carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][0][id] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+
+Get_cart_by_cart_id_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "1"}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Each array element of array in response should contain property: [data][relationships][items][data] id
+ And Each array element of array in response should contain property with value: [included] type items
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+
+Get_cart_by_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+
+Get_cart_with_included_cart_rules
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": 4}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] carts
+ And Response body parameter should be: [data][0][id] ${cart_id}
+ And Response body parameter should be: [data][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][0][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][0][attributes][discounts][0][displayName] 10% off minimum order
+ And Response body parameter should be: [data][0][attributes][discounts][0][amount] 3202
+ And Each array element of array in response should contain property with value: [data][0][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][0][relationships][cart-rules][data] id
+ And Response body parameter should be: [included][0][attributes][amount] 3202
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Get_cart_with_included_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "8"}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts?include=promotional-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] carts
+ And Response body parameter should be: [data][0][id] ${cart_id}
+ And Response body parameter should be: [data][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][0][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][0][attributes][discounts][0][displayName] 10% off minimum order
+ And Response body parameter should be: [data][0][attributes][discounts][0][amount] 6404
+ And Each array element of array in response should contain property with value: [data][0][relationships][promotional-items][data] type promotional-items
+ And Each array element of array in response should contain property: [data][0][relationships][promotional-items][data] id
+ And Each array element of array in response should contain property with value: [included] type promotional-items
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should be in: [included][0][attributes][sku] 112 068
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+
+Get_cart_by_cart_id_with_included_vouchers
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND Save the result of a SELECT DB query to a variable: select code from spy_discount_voucher where fk_discount_voucher_pool = 1 and id_discount_voucher = 1 discount_voucher_code
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a GET request: /carts/${cart_id}?include=vouchers
+ Then Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount.discount_2.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+
+#PATCH requests
+Update_cart_by_cart_id_with_all_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${ETag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${ETag}
+ ... AND I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}"}}}
+ ... AND Response status code should be: 200
+
+Update_cart_with_empty_priceMod_currency_store
+# Spryker is designed so that we can send empty attributes: priceMod, currency, store and it will not be changed to the empty values.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${ETag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/negative.robot
new file mode 100644
index 0000000..990e9b6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/negative.robot
@@ -0,0 +1,229 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+Add_item_to_guest_cart_non_existing_sku
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+
+Add_item_to_guest_cart_with_missing_x_anonymous_customer_id
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Add_item_to_guest_cart_with_wrong_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items {"data": {"type": "fake","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_item_to_guest_cart_with_missing_properties
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_item_to_guest_cart_with_invalid_properties
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+
+
+
+####### PATCH #######
+Update_item_in_guest_cart_with_not_matching_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous-customer-id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku} {"data": {"type": "guest-cart-items","attributes": {"quantity": "1"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_guest_cart_with_non_existing_item_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items/fake {"data": {"type": "guest-cart-items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Update_item_in_guest_cart_with_no_item_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_item_in_guest_cart_with_non_existing_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a PATCH request: /guest-carts/fake/guest-cart-items/fake {"data": {"type": "guest-cart-items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_guest_cart_with_no_cart_id
+ When I send a PATCH request: /guest-carts//guest-cart-items/fake {"data": {"type": "guest-cart-items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_item_in_guest_cart_with_invalid_parameters
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku} {"data": {"type": "guest-cart-items","attributes": {"quantity": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+
+Update_item_in_guest_cart_with_invalid_properties
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku} {"data": {"type": "guest-cart-items","attributes": {"quantity": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+
+
+
+####### DELETE #######
+Delete_cart_item_with_not_matching_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous-customer-id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_without_guest_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a DELETE request: /guest-carts//guest-cart-items/${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a DELETE request: /guest-carts/fake/guest-cart-items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/positive.robot
new file mode 100644
index 0000000..57cb09c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_cart_items/positive.robot
@@ -0,0 +1,269 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+Add_items_to_guest_cart_with_items_include
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items?include=items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 3}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [included][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 4
+ And Response body parameter should be: [included][0][attributes][groupKey] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][configuredBundle] None
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem] None
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][calculations][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][calculations][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][calculations][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][calculations][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] 0
+
+Change_item_qty_in_guest_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku}?include=items {"data": {"type": "guest-cart-items","attributes": {"quantity": "10"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 10
+
+Remove_item_from_guest_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items/${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ And I send a GET request: /guest-carts/${guest_cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+
+Add_items_to_guest_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items?include=items,concrete-products,abstract-products {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ #included
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include should contain certain entity type: guest-cart-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response include element has self link: guest-cart-items
+ And Each array element of array in response should contain a nested array of a certain size: [included] [relationships] 1
+ And Response should contain the array of a certain size: [included][0][relationships][abstract-products][data] 1
+ And Response should contain the array of a certain size: [included][1][relationships][abstract-products][data] 1
+ And Response should contain the array of a certain size: [included][2][relationships][concrete-products][data] 2
+ And Response should contain the array of a certain size: [included][3][relationships][concrete-products][data] 1
+
+Add_items_to_guest_cart_with_included_cart_rules
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items?include=cart-rules {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 10}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body parameter should be: [included][0][type] cart-rules
+ And Response body parameter should not be EMPTY: [included][0][id]
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][discountType]
+ And Response body parameter should not be EMPTY: [included][0][attributes][displayName]
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+
+Add_items_to_guest_cart_with_included_promotional_products
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items?include=promotional-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 100}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body parameter should be: [included][0][type] promotional-items
+ And Response body parameter should not be EMPTY: [included][0][id]
+ And Response body parameter should be in: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.promotional_items_sku} ${concrete_product_with_concrete_product_alternative.promotional_items_sku1} ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be in: [included][0][attributes][quantity] 1 111
+ And Response body parameter should be in: [included][0][attributes][skus] ${concrete_product_with_concrete_product_alternative.promotional_items_sku} ${concrete_product_with_concrete_product_alternative.promotional_items_sku1} ${concrete_product_with_concrete_product_alternative.sku}
+
+Add_items_to_guest_cart_with_included_bundle_items
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items?include=bundle-items,bundled-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${bundle_product.concrete_sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response should contain the array of a certain size: [data][relationships][bundle-items][data] 1
+ And Response should contain the array of a certain size: [included] 5
+ And Response include should contain certain entity type: bundle-items
+ And Response include should contain certain entity type: bundled-items
+ And Response include element has self link: bundle-items
+ And Response include element has self link: bundled-items
+ And Response body parameter should be: [included][0][type] bundled-items
+ And Response body parameter should be: [included][0][attributes][sku] ${bundled.product_1.concrete_sku}
+ And Response body parameter should be: [included][1][type] bundled-items
+ And Response body parameter should be: [included][1][attributes][sku] ${bundled.product_2.concrete_sku}
+ And Response body parameter should be: [included][2][type] bundled-items
+ And Response body parameter should be: [included][2][attributes][sku] ${bundled.product_3.concrete_sku}
+ And Response body parameter should be: [included][3][type] bundle-items
+ And Response body parameter should be: [included][3][attributes][sku] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 1
+ And Response body parameter should be: [included][3][attributes][groupKey] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [included][3][attributes][abstractSku] ${bundle_product.abstract_sku}
+
+Add_a_configurable_product_to_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Update_configurable_product_quantity_in_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_uid}?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /guest-carts/${guest_cart_id}?include=guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/negative.robot
new file mode 100644
index 0000000..fb1943a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/negative.robot
@@ -0,0 +1,91 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart spryker-core
+
+*** Test Cases ***
+Get_guest_cart_without_anonymous_customer_unique_id
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_empty_anonymous_customer_unique_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_non_existing_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a GET request: /guest-carts/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_wrong_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_empty_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Update_guest_cart_with_wrong_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/fake {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_without_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/ {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_guest_cart_with_invalid_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Update_guest_cart_without_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Update_guest_cart_update_price_mode_with_items_in_the_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.net}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 111
+ And Response body parameter should be: [errors][0][detail] Can’t switch price mode when there are items in the cart.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/positive.robot
new file mode 100644
index 0000000..082a994
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/guest_carts/positive.robot
@@ -0,0 +1,223 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax spryker-core customer-access promotions-discounts
+
+*** Test Cases ***
+
+Create_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][0][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][discountTotal]
+ Response body parameter should be greater than: [data][0][attributes][totals][taxTotal] 0
+ Response body parameter should be greater than: [data][0][attributes][totals][subtotal] 0
+ Response body parameter should be greater than: [data][0][attributes][totals][grandTotal] 0
+ Response body parameter should be greater than: [data][0][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_by_id
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_including_cart_items
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][relationships][guest-cart-items][data][0][type] guest-cart-items
+ And Response body parameter should be: [data][relationships][guest-cart-items][data][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should not be EMPTY: [included][0][id]
+ Response should contain the array of a certain size: [included] 1
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+
+Retrieve_guest_cart_including_cart_rules
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Retrieve_guest_cart_including_vouchers
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I send a POST request: /guest-cart-items?include=items {"data": {"type": "guest-cart-items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND Save the result of a SELECT DB query to a variable: select code from spy_discount_voucher where fk_discount_voucher_pool = 1 and id_discount_voucher = 1 discount_voucher_code
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=vouchers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount.discount_2.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Update_guest_cart_with_all_attributes
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Update_guest_cart_with_empty_priceMod_currency_store
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Convert_guest_cart_to_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Create a guest cart: ${random}-convert-guest-cart ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/negative.robot
new file mode 100644
index 0000000..e6feeeb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/negative.robot
@@ -0,0 +1,312 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart product configurable-product inventory-management
+
+*** Test Cases ***
+
+####### POST #######
+Add_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+
+Add_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_item_to_cart_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization="fake"
+ When I send a POST request: /carts/not-existing-cart/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "carts","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+
+Add_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts//items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+
+####### PATCH #######
+Update_item_in_cart_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a PATCH request: /carts/${cart_id}/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Update_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a PATCH request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/fake/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_cart_with_no_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts/not-existing-cart/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a PATCH request: /carts//items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_item_in_cart_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_without_changing_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a PATCH request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 114
+ And Response should return error message: Cart item could not be updated.
+
+Update_item_with_invalid_parameters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a PATCH request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} {"data": {"type": "items","attributes": {"quantity": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+
+####### DELETE #######
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_with_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts//items/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
diff --git a/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/positive.robot
new file mode 100644
index 0000000..1a78823
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/cart_endpoints/items/positive.robot
@@ -0,0 +1,313 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart product product-options non-splittable-products configurable-product promotions-discounts inventory-management
+
+*** Test Cases ***
+
+#####POST#####
+Add_one_item_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_two_items_to_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=items,concrete-products,abstract-products {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "2"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][3][type] items
+ And Response body parameter should be: [included][3][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][3][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 2
+ And Response body parameter should be: [included][3][attributes][groupKey] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][3][attributes][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [included][3][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][3][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][3][attributes][selectedProductOptions] 0
+
+Get_a_cart_with_included_items_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "2"}}}
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response body parameter should be: [included][1][type] items
+ And Response body parameter should be: [included][1][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 2
+ And Response body parameter should be: [included][1][attributes][groupKey] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][1][attributes][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [included][1][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][1][attributes][selectedProductOptions] 0
+
+Add_ten_items_to_cart_with_included_cart_rules_and_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=cart-rules,promotional-items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 10}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: items
+
+Add_bundle_to_cart_with_included_bundle_items_and_bundled_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=bundle-items,bundled-items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete_sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][bundle-items][data] 1
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: bundle-items
+ And Response include should contain certain entity type: bundled-items
+ And Response include element has self link: bundle-items
+ And Response include element has self link: bundled-items
+ And Response body parameter should be: [included][0][type] bundled-items
+ And Response body parameter should be: [included][0][attributes][sku] ${bundled.product_1.concrete_sku}
+ And Response body parameter should be: [included][1][type] bundled-items
+ And Response body parameter should be: [included][1][attributes][sku] ${bundled.product_2.concrete_sku}
+ And Response body parameter should be: [included][2][type] bundled-items
+ And Response body parameter should be: [included][2][attributes][sku] ${bundled.product_3.concrete_sku}
+ And Response body parameter should be: [included][3][type] bundle-items
+ And Response body parameter should be: [included][3][attributes][sku] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 1
+ And Response body parameter should be: [included][3][attributes][groupKey] ${bundle_product.concrete_sku}
+ And Response body parameter should be: [included][3][attributes][abstractSku] ${bundle_product.abstract_sku}
+
+Add_product_with_options_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type": "items","attributes":{"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1,"productOptions": [{ "sku": "${product.option_1}"},{ "sku": "${product.option_2}"}] }}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: items
+ And Response include element has self link: items
+ And Response body parameter should contain: [included][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should contain: [included][0][attributes][groupKey] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitProductOptionPriceAggregation] 1
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumProductOptionPriceAggregation] 1
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 2
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] optionGroupName
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] sku
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] optionName
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] price
+
+Change_item_qty_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "1"}}}
+ When I send a PATCH request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}?include=items {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+
+####### DELETE #######
+Delete_item_form_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "1"}}}
+ ... AND Save value to a variable: [included][0][attributes][groupKey] item_group_key
+ When I send a DELETE request: /carts/${cart_id}/items/${item_group_key}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Update_configurable_product_quantity_in_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/negative.robot
new file mode 100644
index 0000000..f524978
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue category-management
+
+*** Test Cases ***
+Get_category_node_by_invalid_id
+ When I send a GET request: /category-nodes/test
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
+
+Get_category_node_by_non_exist_id
+ When I send a GET request: /category-nodes/111111
+ Then Response status code should be: 404
+ And Response should return error code: 703
+ And Response should return error message: "Cant find category node with the given id."
+
+Get_absent_category_node
+ When I send a GET request: /category-nodes
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/positive.robot
new file mode 100644
index 0000000..0714d57
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/category_endpoints/category_nodes/positive.robot
@@ -0,0 +1,59 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue category-management
+
+*** Test Cases ***
+Get_category_node_is_root_by_id
+ When I send a GET request: /category-nodes/${category_node.root_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.root_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][parents] 0
+ And Response should contain the array larger than a certain size: [data][attributes][children] 1
+ And Response body has correct self link internal
+
+Get_category_node_has_children_by_id
+ When I send a GET request: /category-nodes/${category_node.children_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.children_id}
+ And Response body parameter should be: [data][attributes][nodeId] ${category_node.children_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] nodeId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] name
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] order
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] children
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] parents
+ And Response body has correct self link internal
+
+
+Get_category_node_that_has_only_parents_by_id
+ When I send a GET request: /category-nodes/${category_node.parent_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node.parent_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][children] 0
+ And Response should contain the array larger than a certain size: [data][attributes][parents] 0
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/negative.robot
new file mode 100644
index 0000000..83fdb2f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/negative.robot
@@ -0,0 +1,391 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout shipment order-management configurable-bundle promotions-discounts gift-cards configurable-product spryker-core
+
+*** Test Cases ***
+#POST requests
+Create_order_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_order_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1105
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+
+Create_order_for_guest_user_without_anonymous_id
+ [Setup] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND I send a POST request: /guest-cart-items {"data": { "type": "guest-cart-items", "attributes": {"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}", "quantity": "1"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1105
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+
+Create_order_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_order_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "fake_email","salutation": "Ms","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+
+Create_order_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Create_order_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Create_order_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Billing address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+
+Create_order_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shipments": [{"requestedDeliveryDate": "2021-09-29", "idShipmentMethod": 1, "items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"], "shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false}}],"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+
+Create_order_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_payment.method_name"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Checkout payment is not valid
+
+Create_order_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+
+Create_order_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+
+Create_order_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Shipment method not found.
+ And Response should return error code: 1102
+
+Create_order_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+
+Create_order_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": []}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1104
+ And Response should return error message: Cart is empty.
+
+Create_order_with_higher_order_total_price_than_threshold_limit
+ [Documentation] threeshold is 10000 thats why i changed to 78 (sales price for product is 129.38 )
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.threshold_limit.sku}","quantity": 78}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product.threshold_limit.sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: The cart value cannot be higher than €10,000.00. Please remove some items to proceed with the order
+
+Create_order_with_regular_shipment_&_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipment": {"idShipmentMethod": 0},"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4301
+ And Response should return error message: Single and multiple shipments attributes are not allowed in the same request.
+
+Create_order_with_split_shipments_&_invalid_shipment.delivery_date
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "None"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": "None"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shipments.0.requestedDeliveryDate => This value is not a valid date.
+ And Array in response should contain property with value: [errors] detail shipments.1.requestedDeliveryDate => This value is not a valid date.
+
+Create_order_with_split_shipments_&_invalid_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_split_shipments_&_empty_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4302
+ And Response should return error message: Provided address is not valid. You can either provide address ID or address fields.
+
+Create_order_with_split_shipments_&_without_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: shipments.1.shippingAddress => This value should not be blank.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/positive.robot
new file mode 100644
index 0000000..a446fc9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout/positive.robot
@@ -0,0 +1,535 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart checkout shipment order-management configurable-bundle promotions-discounts gift-cards configurable-product payments inventory-management default-run-feature
+
+*** Test Cases ***
+#POST requests
+Create_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_for_guest_user
+ [Setup] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND I send a POST request: /guest-cart-items {"data": { "type": "guest-cart-items", "attributes": {"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}", "quantity": "1"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_include_orders
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ #totals
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be greater than: [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][unitTaxAmount]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][sumTaxAmount]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${bundle_product.concrete_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${bundled.product_1.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${bundled.product_1.concrete_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${bundled.product_2.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${bundled.product_2.concrete_name}
+ And Response body parameter should be: [included][0][attributes][items][2][sku] ${bundled.product_3.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][2][name] ${bundled.product_3.concrete_name}
+ And Response body has correct self link internal
+
+Create_order_with_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ ... AND I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.chf.code}","store": "${store.de}"}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 20}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 5},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_5}
+ And Response body has correct self link internal
+
+Create_order_with_product_options
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1, "productOptions": [{"sku": "${product.option_1}"}]}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}", "${concrete_product.with_options.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response should contain the array of a certain size: [included][0][attributes][items] 2
+ And Response body has correct self link internal
+ #product_1
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ #product_2
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][optionGroupName] Warranty
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][sku] ${product.option_1}
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][optionName] ${product.option_1_name}
+ And Response body parameter should be greater than: [included][0][attributes][items][1][productOptions][0][price] 0
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+
+Create_order_with_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [included][0][attributes][shipments] 0
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 2
+
+Create_order_with_split_shipments_&_same_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+
+Create_order_with_same_items_in_different_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 1
+
+Create_order_with_free_shipping_discount
+ [Documentation] change sub total cause product price is 26.25 (sub total could not be greater than 200.00)
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 3}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [included][0][attributes][totals][expenseTotal] ${discount.discount_1.total_sum}
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 7800
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount.discount_1.total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [included][0][attributes][items] 3
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultGrossPrice] ${discount.discount_1.total_sum}
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount.discount_1.total_sum}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount.discount_1.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount.discount_1.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+
+Create_order_with_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_product.sku_1}"]}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ # #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_product.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_product.sku_1}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxRateAverageAggregation] 0.00
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesOrderItemConfiguration][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
diff --git a/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/negative.robot
new file mode 100644
index 0000000..aa8f34d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/negative.robot
@@ -0,0 +1,249 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment spryker-core
+
+*** Test Cases ***
+#POST requests
+Provide_checkout_data_with_invalid_access_token
+ [Documentation] Created the bug-ticket https://spryker.atlassian.net/browse/CC-16699
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Provide_checkout_data_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1105
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+
+Provide_checkout_data_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Provide_checkout_data_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Provide_checkout_data_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Provide_checkout_data_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "fake_email","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+
+Provide_checkout_data_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Provide_checkout_data_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Provide_checkout_data_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+
+Provide_checkout_data_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+
+Provide_checkout_data_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+
+Provide_checkout_data_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+
+Provide_checkout_data_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+
+Provide_checkout_data_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+
+Provide_checkout_data_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/positive.robot
new file mode 100644
index 0000000..d56f9c7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/checkout_endpoints/checkout_data/positive.robot
@@ -0,0 +1,193 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment spryker-core
+
+*** Test Cases ***
+#POST requests
+
+Provide_checkout_data
+ [Documentation] Created a new bug https://spryker.atlassian.net/browse/CC-23077 (not a bug, changed bihavior https://docs.spryker.com/docs/pbc/all/carrier-management/202212.0/manage-via-glue-api/retrieve-shipments-and-shipment-methods-when-submitting-checkout-data.html#response)
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] checkout_item_1
+ When I send a POST request: /checkout-data?include=shipments {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName":"${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress":{"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipments": [{"items": ["${checkout_item_1}"],"shippingAddress": {"id": "null","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode":"${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "2021-09-29"}]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][id] 1
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][name] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [included][0][attributes][selectedShipmentMethod][price] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][taxRate] ${tax_rate}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+Provide_checkout_with_only_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data", "attributes": {"idCart": "${cart_id}","payments": []}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+
+Provide_checkout_data_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] checkout_item_1
+ When I send a POST request: /checkout-data?include=shipments {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName":"${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress":{"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fale_last_name","address1": "fake_address1","address2": "fale_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_isoCode","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipments": [{"items": ["${checkout_item_1}"],"shippingAddress": {"id": "null","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode":"${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "2021-09-29"}]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][id] 1
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][name] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [included][0][attributes][selectedShipmentMethod][price] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][taxRate] ${tax_rate}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+Provide_checkout_data_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] checkout_item_1
+ When I send a POST request: /checkout-data?include=shipments {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName":"${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress":{"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipments": [{"items": ["${checkout_item_1}"],"shippingAddress": {"id": "null","salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode":"fake_zipcode","city": "fake_city","iso2Code": "fake_iso2code","company": "fake_company","phone": "fake_phone"},"idShipmentMethod": 1,"requestedDeliveryDate": "2021-09-29"}]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][id] 1
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][name] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [included][0][attributes][selectedShipmentMethod][price] 0
+ And Response body parameter should be in: [included][0][attributes][selectedShipmentMethod][taxRate] ${tax_rate} ${tax_rate1}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+
+
+Provide_checkout_data_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] checkout_item_1
+ When I send a POST request: /checkout-data?include=shipments {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName":"${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress":{"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_provider_method"}],"shipments": [{"items": ["${checkout_item_1}"],"shippingAddress": {"id": "null","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode":"${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "2021-09-29"}]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][id] 1
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][name] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [included][0][attributes][selectedShipmentMethod][price] 0
+ And Response body parameter should be in: [included][0][attributes][selectedShipmentMethod][taxRate] ${tax_rate} ${tax_rate1}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+
+
+Provide_checkout_data_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+
+Provide_checkout_data_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+
+
+Provide_checkout_data_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data?include=shipments {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName":"${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress":{"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipments": [{"items": ["${bundle_product.concrete_sku}"],"shippingAddress": {"id": "null","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode":"${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "2021-09-29"}]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][id] 1
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][name] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [included][0][attributes][selectedShipmentMethod][price] 0
+ And Response body parameter should be in: [included][0][attributes][selectedShipmentMethod][taxRate] ${tax_rate} ${tax_rate1}
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][selectedShipmentMethod][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
new file mode 100644
index 0000000..48c0cfe
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Get_abstract_product_alternative_for_concrete_product_with_invalid_sku_of_product
+ When I send a GET request: /concrete-products/65789/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response body parameter should be: [errors][0][detail] Concrete product is not found.
+
+Get_abstract_product_alternative_for_concrete_product_using_abstract_product_SKU
+ When I send a GET request: /concrete-products/${bundled.product_1.abstract_sku}/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response body parameter should be: [errors][0][detail] Concrete product is not found.
+
+Get_abstract_product_alternative_for_concrete_product_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
new file mode 100644
index 0000000..4ae25b1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
@@ -0,0 +1,55 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product discontinued-products alternative-products
+
+*** Test Cases ***
+Get_concrete_alternative_product_for_a_product_that_has_none
+ When I send a GET request: /concrete-products/${bundled.product_1.concrete_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response reason should be: OK
+
+Get_concrete_alternative_product
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response body should contain: id
+ And Response body parameter should not be EMPTY: [data][0][attributes][sku]
+ And Response body parameter should contain: [data][0][attributes] isDiscontinued
+ And Response body parameter should contain: [data][0][attributes] discontinuedNote
+ And Response body parameter should contain: [data][0][attributes] averageRating
+ And Response body parameter should contain: [data][0][attributes] reviewCount
+ And Response body parameter should not be EMPTY: [data][0][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should contain: [data][0][attributes] attributes
+ Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 3
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should contain: [data][0][attributes] attributeNames
+ And Response should contain the array of a certain size: [data][0][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][0][attributes][attributeNames] 6
+ And Response body has correct self link
+
+Get_concrete_alternative_product_with_include
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}/concrete-alternative-products?include=concrete-product-image-sets,concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+ And Response include element has self link: concrete-product-prices
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
new file mode 100644
index 0000000..14e587b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
new file mode 100644
index 0000000..4959bac
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_concrete_SKU_with_stock
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_product_with_stock2}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${product_availability.concrete_available_product_with_stock2}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_with_stock_and_never_out_of_stock
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku1}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku1}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0.0000000000
+ And Response body has correct self link
+
+
+Request_concrete_availability_by_concrete_SKU_without_stock
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_product_without_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${product_availability.concrete_available_product_without_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
new file mode 100644
index 0000000..61c348d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_image_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundled.product_1.abstract_sku}/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
+
+Request_product_image_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
new file mode 100644
index 0000000..21d1c10
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
@@ -0,0 +1,33 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_product_with_one_image_set
+ When I send a GET request: /concrete-products/${concrete_product.one_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_product.one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+
+Request_concrete_product_with_multiple_images
+ When I send a GET request: /concrete-products/${concrete_product.multiple_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_product.multiple_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 19
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
new file mode 100644
index 0000000..10cbcf2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Request_product_prices_with_abstract_sku
+ When I send a GET request: /concrete-products/${bundled.product_1.abstract_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Request_product_prices_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_prices_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_prices_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
new file mode 100644
index 0000000..13a0c07
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
@@ -0,0 +1,53 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Request_concrete_product_with_only_default_price
+ When I send a GET request: /concrete-products/${concrete_product.one_image_set.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_product.one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should be greater than: [data][0][attributes][price] 1
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][grossAmount] 1
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+
+Request_concrete_product_with_default_and_original_prices
+ When I send a GET request: /concrete-products/${concrete_product.original_prices.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices][0][grossAmount]
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${array}
+
+Request_concrete_product_with_volume_product_prices
+ When I send a GET request: /concrete-products/${concrete_product.volume_prices.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete_product.volume_prices.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be: [data][0][attributes][prices][0][volumePrices][0][grossAmount] ${concrete_product.volume_prices_gross.amount}
+ And Response body parameter should be: [data][0][attributes][prices][0][volumePrices][0][netAmount] ${concrete_product.volume_prices_net.amount}
+ And Response body parameter should be: [data][0][attributes][prices][0][volumePrices][0][quantity] 5
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/negative.robot
new file mode 100644
index 0000000..214f7e3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/negative.robot
@@ -0,0 +1,35 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_concrete_with_product_doesn't_exist
+ When I send a GET request: /concrete-products/354656u7i8
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundled.product_1.abstract_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+
+Request_product_concrete_with_empty_SKU
+ When I send a GET request: /concrete-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_concrete_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/positive.robot
new file mode 100644
index 0000000..5b149bb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/concrete_products_endpoints/concrete_products/positive.robot
@@ -0,0 +1,92 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_concrete_by_id
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product_with_concrete_product_alternative.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+
+Request_product_concrete_with_included_image_sets
+ When I send a GET request: /concrete-products/${concrete_product.one_image_set.sku}?include=concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.one_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.one_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 1
+ And Response should contain the array of a certain size: [data][attributes][attributes] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+
+Request_product_concrete_with_included_availabilities_and_product_prices
+ When I send a GET request: /concrete-products/${concrete_product.original_prices.sku}?include=concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.original_prices.name}
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-availabilities
+
+Request_product_concrete_with_included_product_labels_and_product_options
+ [Setup] Trigger product labels update
+ When I send a GET request: /concrete-products/${concrete_product.original_prices.sku}?include=product-labels,product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.original_prices.name}
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-options
+
+# BUG CC-16490
+Request_product_concrete_with_included_product_reviews
+ When I send a GET request: /concrete-products/${concrete_product.with_review.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.with_review.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.with_review.name}
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-reviews
+
+Request_product_concrete_with_included_abstract_product
+ When I send a GET request: /concrete-products/${concrete_product.multiple_image_set.sku}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.multiple_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.multiple_image_set.set_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
new file mode 100644
index 0000000..f23ce68
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
@@ -0,0 +1,186 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+###### POST ######
+Add_configured_bundle_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "fake","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "fake" not found
+
+Add_configured_bundle_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Add_configured_bundle_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts//configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_configured_bundle_item_to_cart_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization="fake"
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_configured_bundle_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_configured_bundle_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "config","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_configured_bundle_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Add_configured_bundle_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": "","templateUuid": "","items": [{"sku": "","quantity": 2,"slotUuid": ""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Add_configured_bundle_item_to_cart_with_invalid_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": "abc"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 4003
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+####### PATCH #######
+Update_configured_bundle_item_in_cart_with_non_existing_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+
+Update_configured_bundle_item_in_cart_with_invalid_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/${bundle_group_key}?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": "abc"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Update_configured_bundle_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/ {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/fake/configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Update_configured_bundle_item_in_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts//configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 12}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+####### DELETE #######
+Delete_configured_bundle_item_from_the_cart_with_wrong_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+
+Delete_configured_bundle_item_from_the_cart_with_empty_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_item_from_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake/configured-bundles/fake
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Delete_configured_bundle_item_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts//configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
new file mode 100644
index 0000000..bce743d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
@@ -0,0 +1,86 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Add_configured_bundle_item_to_the_cart_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response should contain the array of a certain size: [data][relationships][items] 1
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle_first_slot_item_sku2}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPriceToPayAggregation]
+
+Update_configured_bundle_quantity_in_the cart_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/${bundle_group_key}?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": 8}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle_first_slot_item_sku2}
+ And Response body parameter should be: [included][0][attributes][configuredBundle][quantity] 8
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 4
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+
+Delete_configured_bundle_item_from_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/${bundle_group_key}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot
new file mode 100644
index 0000000..eecd785
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Get_configurable_bundle_templates_by_invalid_configurable_bundle_template_id
+ When I send a GET request: /configurable-bundle-templates/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3901
+ And Response should return error message: Configurable bundle template not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot
new file mode 100644
index 0000000..486cc7b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot
@@ -0,0 +1,109 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Get_configurable_bundle_templates
+ When I send a GET request: /configurable-bundle-templates
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_with_uuid
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response body has correct self link internal
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_slots
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-slots
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] relationships configurable-bundle-template-slots
+ And Each array element of array in response should contain property with value: [included] type configurable-bundle-template-slots
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_image_sets
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] relationships configurable-bundle-template-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes images
+ And Each array element of array in response should contain nested property: [included] [attributes][images] externalUrlLarge
+ And Each array element of array in response should contain nested property: [included] [attributes][images] externalUrlSmall
+ And Each array element of array in response should contain property with value: [included] type configurable-bundle-template-image-sets
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_by_configurable_bundle_template_1_uuid
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}?include=configurable-bundle-template-slots,configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should be: [data][id] ${configurable_bundle_template_1_uuid}
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response should contain the array of a certain size: [data][relationships][configurable-bundle-template-slots][data] 4
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-slots][data] type configurable-bundle-template-slots
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response should contain the array of a certain size: [data][relationships][configurable-bundle-template-image-sets][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-image-sets][data] type configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Response include should contain certain entity type: configurable-bundle-template-slots
+ And Response include should contain certain entity type: configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property: [included][4][attributes][images] externalUrlLarge
+ And Each array element of array in response should contain property: [included][4][attributes][images] externalUrlSmall
+
+Get_configurable_bundle_templates_including_concrete_products_concrete_product_prices_concrete_product_image_sets
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}?include=configurable-bundle-template-slots,concrete-products,concrete-product-prices,concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should be: [data][id] ${configurable_bundle_template_1_uuid}
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array larger than a certain size: [data][relationships][configurable-bundle-template-slots][data] 3
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-slots][data] type configurable-bundle-template-slots
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response include should contain certain entity type: configurable-bundle-template-slots
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-products
+ And Response include element has self link: configurable-bundle-template-slots
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot
new file mode 100644
index 0000000..ae8c91b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot
@@ -0,0 +1,219 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle spryker-core cart
+
+*** Test Cases ***
+### POST ###
+Add_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts/not_a_cart/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Add_configured_bundle_with_empty_anonymous_id
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Add_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_with_empty_template_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4002
+ And Response should return error message: Configurable bundle template not found.
+
+Add_configured_bundle_with_nonexistant_template_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "not_uuid","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4002
+ And Response should return error message: Configurable bundle template not found.
+
+Add_configured_bundle_with_empty_slot_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": ""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Configured bundle cannot be added to cart.
+
+Add_configured_bundle_with_nonexistant_slot_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "not_uuid"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Configured bundle cannot be added to cart.
+
+Add_configured_bundle_with_zero_quantity
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 0,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: "Wrong quantity for product SKU ${configurable_bundle.slot_1.product_1}."
+
+Add_configured_bundle_with_empty_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "" not found
+
+Add_configured_bundle_with_invalid_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "not_a_sku","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "not_a_sku" not found
+
+Add_configured_bundle_with_abstract_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${special_product_abstract_sku.with_multivariant}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "${special_product_abstract_sku.with_multivariant}" not found
+
+Add_configured_bundle_with_product_not_in_stock
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_no_stock}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Item ${configurable_bundle.slot_1.product_no_stock} no longer available.
+
+
+### PATCH ###
+
+Update_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a PATCH request: /guest-carts/not_a_cart/guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_with_empty_anonymous_id
+ When I send a PATCH request: /guest-carts//guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Update_configured_bundle_quantity_to_zero
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 0}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Update_configured_bundle_with_empty_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Update_configured_bundle_with_invalid_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/not_a_bundle {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+### DELETE ###
+
+Delete_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a DELETE request: /guest-carts/not_a_cart/guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_with_empty_anonymous_id
+ When I send a DELETE request: /guest-carts//guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Delete_configured_bundle_with_empty_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_configured_bundle_with_invalid_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/not_a_bundle
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot
new file mode 100644
index 0000000..1720ce7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot
@@ -0,0 +1,291 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle cart spryker-core promotions-discounts non-splittable-products
+
+*** Test Cases ***
+### POST ###
+Add_configured_bundle_with_1_slot_1_product_new_cart
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 1
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_with_multiple_slots_and_products_to_existing_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${concrete_available_product.sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_6.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_6_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 1
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_cart_rules
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles?include=cart-rules {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: cart-rules
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][cart-rules][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_guest_cart_items
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][guest-cart-items][data] type guest-cart-items
+ And Each array element of array in response should contain property: [data][relationships][guest-cart-items][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPriceToPayAggregation]
+ And Each array element of array in response should contain value: [included] configuredBundle
+ And Response body parameter should be: [included][0][attributes][configuredBundle][quantity] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][groupKey]
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][template]
+ And Response body parameter should be: [included][0][attributes][configuredBundle][template][uuid] ${configurable_bundle_template_2_uuid}
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][template][name]
+ And Each array element of array in response should contain value: [included] configuredBundleItem
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem][quantityPerSlot] 1
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem][slot][uuid] ${configurable_bundle_slot_5_uuid}
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 0
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_concrete_products
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles?include=concrete-products,guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: concrete-products
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should not be EMPTY: [included][0][attributes][sku]
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDiscontinued]
+ And Response body parameter should be: [included][0][attributes][discontinuedNote] None
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][description]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes]
+ And Response body parameter should not be EMPTY: [included][0][attributes][superAttributesDefinition]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributeNames]
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_bundle_items
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${bundle_product.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=bundle-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: bundle-items
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][bundle-items][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][bundle-items][data] type bundle-items
+ And Each array element of array in response should contain property: [data][relationships][bundle-items][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Response body parameter should be: [included][0][attributes][configuredBundle] None
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem] None
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Add_same_configured_bundle_again_to_check_quantity_not_merged
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [data][id] guest_cart_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_to_cart_that_contains_same_product
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${configurable_bundle.slot_5.product_1} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_other_configured_bundle_product_with_same_template
+ [Setup] Run Keyword I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [data][id] guest_cart_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_2}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_bundle.slot_5.product_2}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+
+### PATCH ###
+Update_configured_bundle_product_quantity
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}?include=guest-cart-items {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 1
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+### DELETE ###
+Delete_configured_bundle_from_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/negative.robot
new file mode 100644
index 0000000..fe1f924
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_page_list_by_fake_id
+ When I send a GET request: /cms-pages/:cms
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
+Get_cms_page_list_by_wrong_id
+ When I send a GET request: /cms-pages/${abstract_list.product_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/positive.robot
new file mode 100644
index 0000000..22d1632
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/cms_pages/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/cms_steps.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_pages_list
+ When I send a GET request: /cms-pages
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_pages.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body array element should contain property with value at least once: [data] [attributes][name] ${cms_pages.first_cms_page.name}
+ And Response body array element should contain property with value at least once: [data] [attributes][url] ${cms_pages.first_cms_page.url_en}
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value: [data] [attributes][isSearchable] True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body has correct self link
+
+Get_specific_cms_page
+ [Setup] Run Keywords I send a GET request: /cms-pages
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] cms_page_id
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][isSearchable]
+ And Response body should contain: pageKey
+ And Response body should contain: validTo
+ And Response body has correct self link internal
+
+Get_specific_cms_with_includes
+ [Setup] Add content product abstract list to cms page in DB ${cms_pages.cms_page_with_product_lists.id} apl-watches
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_pages.cms_page_with_product_lists.id}?include=content-product-abstract-lists
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_pages.cms_page_with_product_lists.id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should be: [data][attributes][name] ${cms_pages.cms_page_with_product_lists.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][content-product-abstract-lists][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: content-product-abstract-lists
+ And Response include element has self link: content-product-abstract-lists
+ [Teardown] Run Keyword Delete latest cms page version by uuid from DB ${cms_pages.cms_page_with_product_lists.id}
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/negative.robot
new file mode 100644
index 0000000..dcea715
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner_without_id
+ When I send a GET request: /content-banners
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_banner_with_wrong_content_id_type
+ When I send a GET request: /content-banners/${abstract_list.product_id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 2203
+ And Response should return error message: Content type is invalid.
+
+Get_banner_with_invalid_content_id
+ When I send a GET request: /content-banners/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/positive.robot
new file mode 100644
index 0000000..4991e33
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_banners/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner
+ When I send a GET request: /content-banners/${banner_1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${banner_1.id}
+ And Response body parameter should be: [data][type] content-banners
+ And Response body parameter should be: [data][attributes][title] ${banner_1.name}
+ And Response body parameter should not be EMPTY: [data][attributes][subtitle]
+ And Response body parameter should contain: [data][attributes][imageUrl] png
+ And Response body parameter should not be EMPTY: [data][attributes][clickUrl]
+ And Response body parameter should be: [data][attributes][altText] ${banner_1.name}
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot
new file mode 100644
index 0000000..b8d2f10
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Get_abstract_product_list_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_products_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_with_no_id
+ When I send a GET request: /content-product-abstract-lists
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_missing_id
+ When I send a GET request: /content-product-abstract-lists//abstract-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_no_id
+ When I send a GET request: /content-product-abstract-lists/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot
new file mode 100644
index 0000000..fdf53f1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Abstract_product_list
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+
+Abstract_product_list_abstract_products
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}/abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_list.size}
+ And Each array element of array in response should contain property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_list.product1_sku}
+ And Response body parameter should be: [data][0][attributes][name] ${abstract_list.product1_name}
+ And Response body parameter should be: [data][1][attributes][sku] ${abstract_list.product2_sku}
+ And Response body parameter should be: [data][1][attributes][name] ${abstract_list.product2_name}
+
+
+Abstract_product_list_with_include
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-products][data] ${abstract_list.size}
+ And Response should contain the array of a certain size: [included] ${abstract_list.size}
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/negative.robot
new file mode 100644
index 0000000..d66efad
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/negative.robot
@@ -0,0 +1,285 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+######POST#####
+Create_customer_address_with_missing_required_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address3": "${default.address3}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail city => This field is missing.
+ And Array in response should contain property with value: [errors] detail iso2Code => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultShipping => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultBilling => This field is missing.
+
+Create_customer_address_with_empty_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","country": "","iso2Code": "","company":"","phone": "","isDefaultShipping": "","isDefaultBilling": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+
+Create_customer_address_with_customer_reference_not_matching_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_non_existing_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/DE--10000/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers//addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_type
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+######GET#####
+Get_non-existent_customer_address
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Get_other_customer_address_list
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_address_list_for_non-existent_customer
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/fake/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Get_address_list_with_no_token
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Get_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_other_customer_address_by_id_and_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+######PATCH#####
+Patch_customer_address_without_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Patch_customer_address_with_fake_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses/fake {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Patch_another_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_another_customer_address_by_id_using_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_second_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_no_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers//addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_wrong_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/DE--1/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_empty_required_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": null,"firstName": null,"lastName": null, "address1": null,"address2": null,"zipCode": null,"city": null,"iso2Code": null}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+######DELETE#####
+Delete_customer_address_with_wrong_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Delete_customer_address_with_no_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/positive.robot
new file mode 100644
index 0000000..14b41d5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/addresses/positive.robot
@@ -0,0 +1,245 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+#####POST#####
+Create_customer_address_with_all_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_only_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] None
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] None
+ And Response body parameter should be: [data][attributes][phone] None
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+
+
+Create_customer_address_as_shipping_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": true,"isDefaultBilling": false}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_billing_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": true}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+#GET
+Get_empty_list_of_customer_addresses
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ Response should contain the array of a certain size: [data] 0
+
+Get_list_of_customer_addresses_with_1_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] address_uid
+ And Response body parameter should be: [data][0][type] addresses
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][0][attributes][city] ${default.city}
+ And Response body parameter should be: [data][0][attributes][country] ${default.country}
+ And Response body parameter should be: [data][0][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][0][attributes][company] ${default.company}
+ And Response body parameter should be: [data][0][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][0][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][0][attributes][isDefaultBilling] True
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_list_of_customer_addresses_with_2_addresses
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": true,"isDefaultBilling": true}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] first_address_uid
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Save value to a variable: [data][1][id] second_address_uid
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${second_address_uid}
+ ... AND Response status code should be: 204
+
+#DELETE
+Delete_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/addresses
+ ... AND Response status code should be: 200
+ ... AND Response should contain the array of a certain size: [data] 1
+ ... AND Save value to a variable: [data][0][id] address_uid
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+
+
+#PATCH
+Update_customer_address_several_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ ... AND Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${address_uid}
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${changed.address1}
+ And Response body parameter should be: [data][attributes][address2] ${changed.address2}
+ And Response body parameter should be: [data][attributes][address3] ${changed.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${changed.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/negative.robot
new file mode 100644
index 0000000..1b5e429
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/negative.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Access_restricted_resource_as_not_authorized_customer
+ I send a GET request: /wishlists
+ Response status code should be: 403
+ And Response reason should be: Forbidden
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/positive.robot
new file mode 100644
index 0000000..e7eed4c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_access/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Resources_list_which_customer_can_access
+ I send a GET request: /customer-access
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should contain: [data][0][type] customer-access
+ And Response should contain the array of a certain size: [data][0][attributes] [resourceTypes] 2
+ And Response body parameter should be: [data][0][attributes][resourceTypes][0] wishlists
+ And Response body parameter should be: [data][0][attributes][resourceTypes][1] wishlist-items
+ And Response body has correct self link
+
+Access_restricted_resource_as_authorized_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.label}"}}}
+ ... AND Response status code should be: 201
+ I send a GET request: /wishlists
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][0][type] wishlists
+ And Response body parameter should be: [data][0][id] ${wishlist_id}
+ And Response body parameter should be: [data][0][attributes][numberOfItems] 1
+ And Response body parameter should be: [data][0][attributes][name] ${wishlist_name}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/negative.robot
new file mode 100644
index 0000000..4f04516
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/negative.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation_with_wrong_confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"39085d16b04b34265910c7ea2a35367ggh"}}}
+ Then Response status code should be: 422
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ And Response should return error code: 423
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":""}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_without_confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_type
+ When I send a POST request: /customer-confirmation {"data":{"type":"","attributes":{"registrationKey":"607a17d1c673f461ca40002ea79fddc0"}}}
+ Then Response status code should be: 400
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_already_used_confirmation_key
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 423
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/positive.robot
new file mode 100644
index 0000000..bd22493
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_confirmation/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot
new file mode 100755
index 0000000..d8ff13e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Forgot_password_wrong_email_format
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"xyz"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_empty_email
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_incorrect_type
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot
new file mode 100755
index 0000000..1875547
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Forgot_password_with_all_required_fields_and_valid_data
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/negative.robot
new file mode 100755
index 0000000..7975744
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/negative.robot
@@ -0,0 +1,136 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Suite Setup API_suite_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_not_equal_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field newPassword should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_data_type
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_current_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: newPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password_confirmation
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_non_autorizated_user
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_not_valid_user_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new_additional}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 408
+ And Response should return error message: Invalid password
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_short_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"test","confirmPassword":"test"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_long_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_customer_reference
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/ {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"1234567890123","confirmPassword":"1234567890123"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_mandatory_fields
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/test123 {"data":{"type":"customer-password","attributes":{"newPassword":"${yves_user.password}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_invalid_access_token
+ Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_value_not_matching_password_policy
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"change1234","confirmPassword":"change1234"}}}
+ Response status code should be: 422
+ Response should return error code: 901
+ And Response reason should be: Unprocessable Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/positive.robot
new file mode 100755
index 0000000..774bafe
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_password/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Suite Setup API_suite_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_eighth_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_eighth_user.password}","newPassword":"${yves_eighth_user.password_new}","confirmPassword":"${yves_eighth_user.password_new}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new_additional}"}}}
+ Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new}"}}}
+ And Response status code should be: 201
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/negative.robot
new file mode 100755
index 0000000..8077ced
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/negative.robot
@@ -0,0 +1,85 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_without_customer_id
+ I send a PATCH request: /customer-restore-password/ {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_type
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"fake","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_without_restorePasswordKey
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: restorePasswordKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_password_value
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"","confirmPassword":"${yves_user.password}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_confirmation_password_value
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"${yves_user.password}","confirmPassword":""}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_short_new_password
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"test","confirmPassword":"test"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_long_new_password
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_not_equal_new_password_and_confirm_password
+ When I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 406
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_url
+ When I send a PATCH request: /customer-restorepassword/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/positive.robot
new file mode 100755
index 0000000..46c9891
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/customer_endpoints/customer_restore_password/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_ninth_user.first_name}","lastName":"${yves_ninth_user.last_name}","gender":"${gender.female}","salutation":"${yves_ninth_user.salutation}","email":"${email.name}${random}${email.domain}","password":"${yves_ninth_user.password}","confirmPassword":"${yves_ninth_user.password}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I send a POST request: /customer-forgotten-password {"data": {"type": "customer-forgotten-password","attributes": {"email":"${user_email}"}}}
+ ... AND Save the result of a SELECT DB query to a variable: select restore_password_key from spy_customer where customer_reference = '${user_reference_id}' restore_key
+ When I send a PATCH request: /customer-restore-password/${user_reference_id} {"data":{"type":"customer-restore-password","id":"${user_reference_id}","attributes":{"restorePasswordKey":"${restore_key}","password":"${yves_ninth_user.password_new}","confirmPassword":"${yves_ninth_user.password_new}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${user_email} ${yves_ninth_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/negative.robot
new file mode 100644
index 0000000..ea41847
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/negative.robot
@@ -0,0 +1,351 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue promotions-discounts product-promotions
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_voucher_code_to_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_voucher_code_to_guest_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_invalid_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_empty_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+
+Add_voucher_to_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+
+Add_invalid_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_empty_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_to_guest_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_to_guest_cart_with_invalid_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a POST request: /guest-carts/fake_guest_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_from_another_discount_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_from_another_discount_to_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_without_voucher_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_guest_user_cart_without_voucher_discount
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_from_another_customer_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_from_another_customer_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_empty_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+
+
+#DELETE requests
+Delete_voucher_code_from_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Delete_voucher_code_from_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_invalid_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+
+Delete_empty_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_voucher_from_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_invalid_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_empty_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_from_guest_user_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_cart_id
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ When I send a DELETE request: /guest-carts/fake_guest_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_another_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_another_customer_guest_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/positive.robot
new file mode 100644
index 0000000..a880999
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/discount_endpoints/vouchers/positive.robot
@@ -0,0 +1,151 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart promotions-discounts product-promotions
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount.discount_2.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_voucher_code_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount.discount_2.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_including_vouchers
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ When I send a POST request: /carts/${cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount.discount_2.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+
+Add_voucher_code_to_guest_user_cart_including_vouchers
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount.discount_2.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+
+#DELETE requests
+Delete_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete.product_with_voucher_code.sku}","quantity": 1}}}
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_voucher_code_from_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount.concrete.product_with_voucher_code.sku} 1
+ ... AND Get voucher code by discountId from Database: ${discount.discount_3.id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/negative.robot
new file mode 100644
index 0000000..7427833
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/negative.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-labels
+Resource ../../../../../../resources/common/common_api.robot
+
+
+*** Test Cases ***
+Get_product_label_with_invalid_label_id
+ When I send a GET request: /product-labels/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_with_nonexistend_label_id
+ When I send a GET request: /product-labels/3001
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_without_label_id
+ When I send a GET request: /product-labels
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1202
+ And Response should return error message: Product label id is missing.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/positive.robot
new file mode 100644
index 0000000..5de61b9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_labels/positive.robot
@@ -0,0 +1,59 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue alternative-products product product-labels discontinued-products
+Resource ../../../../../../resources/common/common_api.robot
+
+
+*** Test Cases ***
+Get_new_product_label_by_id
+ When I send a GET request: /product-labels/${label.new_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.new_id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.new}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_sale_product_label_by_id
+ When I send a GET request: /product-labels/${label.sale_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.sale_id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.sale}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_discontinued_product_label_by_id
+ When I send a GET request: /product-labels/${label.discontinued_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.discontinued_id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.discontinued}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_alternatives_product_label_by_id
+ When I send a GET request: /product-labels/${label.alternatives_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.alternatives_id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.alternatives}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/negative.robot
new file mode 100644
index 0000000..0c88526
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_an_attribute_with_non_existent_attribute_id
+ When I send a GET request: /product-management-attributes/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4201
+ And Response should return error message: Attribute not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/positive.robot
new file mode 100644
index 0000000..5dc61f1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_management_attributes/positive.robot
@@ -0,0 +1,100 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_all_product_management_attributes
+ When I send a GET request: /product-management-attributes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 50
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-management-attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes][key]
+ And Response body parameter should not be EMPTY: [data][0][attributes][inputType]
+ And Response body parameter should not be EMPTY: [data][0][attributes][allowInput]
+ And Response body parameter should be in: [data][0][attributes][allowInput] True False
+ And Response body parameter should be in: [data][0][attributes][isSuper] True False
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][value]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain property with value in: [data] [attributes][allowInput] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isSuper] True False
+ And Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] localeName ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][localizedKeys] translation
+ And Each array element of nested array should contain property with value NOT in: [data] [attributes][localizedKeys] translation None
+ And Each array element of array in response should contain nested property: [data] [attributes] values
+ And Each array element of array in response should contain nested property: [data] [attributes][values] value
+ And Each array element of array in response should contain nested property: [data] [attributes][values] localizedValues
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_product_management_attribute_by_id_superattribute
+ When I send a GET request: /product-management-attributes/${product_management.superattribute_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][localeName]
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][translation]
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_free_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_non_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_no_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/negative.robot
new file mode 100644
index 0000000..b6287b0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/negative.robot
@@ -0,0 +1,78 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_a_review_with_non_existent_review_id
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Product review is not found.
+
+Get_a_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews/78
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Create_a_product_review_without_access_token
+ When I send a POST request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Create_a_product_review_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake
+ When I send a POST request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_a_product_review_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews {"data": {"type": "product-review","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_a_product_review_with_missing_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews {"data": {"attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_a_product_review_with_empty_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": "","nickname": "","summary": "","description": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail rating => This value should be greater than or equal to 1.
+ And Array in response should contain property with value: [errors] detail summary => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail nickname => This value should not be blank.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/positive.robot
new file mode 100644
index 0000000..cb1ca3f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_reviews/positive.robot
@@ -0,0 +1,85 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+Resource ../../../../../../resources/common/common_api.robot
+
+
+*** Test Cases ***
+Get_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] type product-reviews
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] rating
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][rating] int
+ And Each array element of array in response should contain nested property: [data] [attributes] nickname
+ And Each array element of array in response should contain nested property: [data] [attributes] summary
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Get_subset_of_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews?page[offset]=1&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][0][attributes][rating]
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Get_product_reviews_for_product_with_no_reviews
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_product_review_by_id
+ [Setup] Run Keywords I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews
+ ... AND Save value to a variable: [data][0][id] review_id
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-reviews/${review_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${review_id}
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][attributes][rating]
+ And Response body parameter should have datatype: [data][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Create_a_product_review
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.with_options.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 202
+ And Response reason should be: Accepted
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] review_id
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should be: [data][attributes][rating] ${review.default_rating}
+ And Response body parameter should be: [data][attributes][nickname] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][summary] ${review.title}
+ And Response body parameter should be: [data][attributes][description] ${review.text}
+ And Response body has correct self link for created entity: ${review_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/negative.robot
new file mode 100644
index 0000000..1ffc2be
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_a_tax_set_with_concrete_sku
+ When I send a GET request: /abstract-products/${concrete_available_product.sku}/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
+
+Get_a_tax_set_with_missing_sku
+ When I send a GET request: /abstract-products//product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_a_tax_set_with_non_existing_sku
+ When I send a GET request: /abstract-products/fake/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/positive.robot
new file mode 100644
index 0000000..6a6d9f4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/product_tax_sets/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_product_tax sets
+ When I send a GET request: /abstract-products/${abstract_product.with_reviews.sku}/product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-tax-sets
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response should contain the array larger than a certain size: [data][0][attributes][restTaxRates] 1
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] name
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] rate
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] country
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/negative.robot
new file mode 100644
index 0000000..8a3190b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Get_related_products_without_abstract_SKU
+ When I send a GET request: /abstract-products//related-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_related_products_for_nonexistent_SKU
+ When I send a GET request: /abstract-products/not_a_SKU/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_related_products_for_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_available_product.sku}/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/positive.robot
new file mode 100644
index 0000000..907e71f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/related_products/positive.robot
@@ -0,0 +1,101 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Product_has_related_products
+ When I send a GET request: /abstract-products/${concrete_available_product.with_stock_one_concrete_with_superattribute.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][4][id] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should not be EMPTY: [data][4][attributes]
+ And Response body parameter should be: [data][4][attributes][sku] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should be: [data][4][attributes][averageRating] None
+ And Response body parameter should be: [data][4][attributes][reviewCount] 0
+ And Response body parameter should be: [data][4][attributes][name] ${product_related_product_with_related_relation.name}
+ And Response body parameter should not be EMPTY: [data][4][attributes][description]
+ And Response body parameter should not be EMPTY: [data][4][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][4][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][4][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][4][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][4][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][4][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][4][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][4][attributes][url]
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributes] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeNames] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Product_has_related_products_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.sku}/related-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-prices][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-image-sets][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][concrete-products][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-availabilities][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-tax-sets][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+
+Product_has_no_related_products
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/negative.robot
new file mode 100644
index 0000000..aa49937
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/negative.robot
@@ -0,0 +1,90 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+#Logged in customer's cart
+Get_upselling_products_with_missing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=invalid
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_upselling_products_without_access_token
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_upselling_products_using_cart_of_other_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+#Guest user cart
+
+Get_upselling_products_with_missing_guest_cart_id
+ When I send a GET request: /guest-carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_empty_anonymous_id
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Get_upselling_products_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/positive.robot
new file mode 100644
index 0000000..18a06d3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/general_product_endpoints/upselling_products/positive.robot
@@ -0,0 +1,289 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+#Logged in customer's cart
+
+Get_upselling_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][7][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][7][attributes]
+ And Response body parameter should be: [data][7][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][7][attributes][averageRating] None
+ And Response body parameter should be: [data][7][attributes][reviewCount] 0
+ And Response body parameter should be: [data][7][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][7][attributes][description]
+ And Response body parameter should not be EMPTY: [data][7][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][7][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][7][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][7][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][7][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][7][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][7][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_plus_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_cart_containing_multiple_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_of_product_without_relations.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_cart_without_upselling_relations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_of_product_without_relations.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+#Guest user cart
+
+Get_upselling_products_for_guest_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][7][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][7][attributes]
+ And Response body parameter should be: [data][7][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][7][attributes][averageRating] None
+ And Response body parameter should be: [data][7][attributes][reviewCount] 0
+ And Response body parameter should be: [data][7][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][7][attributes][description]
+ And Response body parameter should not be EMPTY: [data][7][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][7][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][7][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][7][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][7][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][7][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][7][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][7][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Get_upselling_products_for_guest_cart_plus_includes
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Get_upselling_products_for_guest_cart_containing_multiple_products
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 2
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_of_product_without_relations.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Get_upselling_products_for_guest_cart_without_upselling_relations
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${concrete_of_product_without_relations.sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/negative.robot
new file mode 100644
index 0000000..29da7eb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/negative.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue navigation spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_navigations_by_non_exist_id
+ When I send a GET request: /navigations/testNonExistNavigations
+ Then Response status code should be: 404
+ And Response should return error code: 1601
+ And Response should return error message: Navigation not found.
+
+
+Get_absent_navigations
+ When I send a GET request: /navigations
+ Then Response status code should be: 400
+ And Response should return error code: 1602
+ And Response should return error message: Navigation id not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/positive.robot
new file mode 100644
index 0000000..768f9ac
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/navigation_endpoints/navigations/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core navigation category-management
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+To_retrieve_a_navigation_tree
+ When I send a GET request: /navigations/MAIN_NAVIGATION
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][isActive] bool
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] children
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][nodeType] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][title] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][children] list
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][nodeType]
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][title]
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] children
+ And Response body has correct self link internal
+
+Get_navigation_tree_using_valid_navigation_key_with_category_nodes_included
+ When I send a GET request: /navigations/MAIN_NAVIGATION?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Should Contain The Array Larger Than a Certain Size: [included] 0
+ And Response Should Contain The Array Larger Than a Certain Size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][category-nodes]
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] type
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each Array Element Of Array In Response Should Contain Property With Value: [included] type category-nodes
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes nodeId
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes name
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaTitle
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaKeywords
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaDescription
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes isActive
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes order
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes url
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes children
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes parents
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/negative.robot
new file mode 100644
index 0000000..546f8ba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/negative.robot
@@ -0,0 +1,102 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue order-management spryker-core customer-access
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_order_by_order_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_with_invalid_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/fake_order_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+### Current test commented because it doesn't work while /orders endpoint is available
+#Get_order_without_order_id
+# [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+# ... AND I set Headers: Authorization=${token}
+# When I send a GET request: /orders/
+# Then Response status code should be: 404
+# And Response reason should be: Unprocessable Content
+# And Response should return error message: Missing order id
+# And Response should return error code: 1100
+
+
+Get_order_by_order_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+Get_customer_orders_list_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_customer_orders_list_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_customer_orders_list_with_invalid_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/yves_user.reference/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/positive.robot
new file mode 100644
index 0000000..e135da2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/order_endpoints/orders/positive.robot
@@ -0,0 +1,547 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue cart checkout order-management product product-bundles measurement-units packaging-units non-splittable-products shipment configurable-bundle configurable-product gift-cards spryker-core customer-access
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+# #GET requests
+Get_order_by_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [data][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][items][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [data][attributes][expenses][0][name] ${shipment.method_name}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should contain: [data][attributes][expenses][0] unitTaxAmount
+ And Response body parameter should contain: [data][attributes][expenses][0] sumTaxAmount
+ And Response body parameter should contain: [data][attributes][expenses][0] unitTaxAmount
+ And Response body parameter should contain: [data][attributes][expenses][0] unitPriceToPayAggregation
+ And Response body parameter should contain: [data][attributes][expenses][0] sumPriceToPayAggregation
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${bundle_product.concrete_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Each array element of array in response should contain property with value: [data][attributes][items] bundleItemIdentifier ${None}
+ And Each array element of array in response should contain property: [data][attributes][items] relatedBundleItemIdentifier
+ And Response body parameter should be: [data][attributes][items][0][name] ${bundled.product_1.concrete_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${bundled.product_1.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][1][name] ${bundled.product_2.concrete_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${bundled.product_2.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][2][name] ${bundled.product_3.concrete_name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${bundled.product_3.concrete_sku}
+ #bundleItems
+ And Response body parameter should be: [data][attributes][bundleItems][0][name] ${bundle_product.product_name}
+ And Response body parameter should be: [data][attributes][bundleItems][0][sku] ${bundle_product.concrete_sku}
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumGrossPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRate] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][refundableAmount] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][canceledAmount] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRateAverageAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][orderReference] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][uuid] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][isReturnable] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][idShipment] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][bundleItemIdentifier] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [data][attributes][bundleItems][0][metadata][image]
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][calculatedDiscounts] 0
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][productOptions] 0
+ And Response body has correct self link internal
+
+
+
+Get_customer_orders_list_without_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ When I send a GET request: /orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+
+Get_customer_orders_list_without_order_id_with_pagination
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND I send a GET request: /orders
+ ... AND Save value to a variable: [data][2][id] order_id
+ When I send a GET request: /customers/${yves_user.reference}/orders?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] orders
+ And Response body parameter should be: [data][0][id] ${order_id}
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+
+Get_order_by_order_id_with_different_items_and_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 2}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be: [data][attributes][items][2][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][2][quantity] 1
+
+
+
+
+Get_order_by_order_id_with_nonsplit_item
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 10}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 1
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 10
+
+
+
+Get_order_by_order_id_with_net_mode_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 20}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 2},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 20
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_2}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+
+
+
+
+Get_order_by_order_id_with_split_shipment
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+
+
+
+Get_order_by_order_id_with_split_shipment_&_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.with_options.sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product.with_options.sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}?include=order-shipments
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete_product.with_options.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete_product.with_options.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value: [data][relationships][order-shipments][data] type order-shipments
+ And Each array element of array in response should contain property: [data][relationships][order-shipments][data] id
+ And Response should contain the array of a certain size: [included] 2
+ #included 1
+ And Response body parameter should be: [included][0][type] order-shipments
+ And Response body parameter should be greater than: [included][0][id] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][itemUuids][0]
+ And Response body parameter should be: [included][0][attributes][methodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][requestedDeliveryDate] ${shipment.delivery_date}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][0][links]
+ #included 2
+ And Response body parameter should be: [included][1][type] order-shipments
+ And Response body parameter should be greater than: [included][1][id] 0
+ And Response body parameter should not be EMPTY: [included][1][attributes][itemUuids][0]
+ And Response body parameter should be: [included][1][attributes][methodName] ${shipment.method_name}
+ And Response body parameter should be: [included][1][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][1][attributes][requestedDeliveryDate] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address1] ${changed.address1}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address2] ${changed.address2}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address3] ${changed.address3}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][phone] ${changed.phone}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][1][links]
+
+
+
+Get_customer_orders_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_order_by_order_id_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 3}}}
+ ... AND Save value to a variable: [included][0][id] item_shipping_order
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_shipping_order}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] ${discount.discount_1.total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 7800
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount.discount_1.total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][shipments][0][defaultGrossPrice] ${discount.discount_1.total_sum}
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount: ${discount.discount_1.total_sum}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName: ${discount.discount_1.name}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description: ${discount.discount_1.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 1
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/return_reasons/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/return_reasons/positive.robot
new file mode 100644
index 0000000..fa9fb65
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/return_reasons/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue return-management
+
+*** Test Cases ***
+#GET requests
+Get_return_reason
+ When I send a GET request: /return-reasons
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type return-reasons
+ And Each array element of array in response should contain nested property: [data] [attributes] reason
+ And Response should contain the array of a certain size: [data] ${return_reasons_qty}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/negative.robot
new file mode 100644
index 0000000..8f9ca90
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/negative.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+ ####POST####
+Create_a_return_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_a_return_with_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_return_for_order_item_that_cannot_be_returned
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_second_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_available_product.sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_with_invalid_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_reason
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"920fc22f-3fb6-53ec-bc5e-c4d321115462","reason":""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+
+####GET####
+Get_lists_of_returns_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /returns
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+
+Get_lists_of_returns_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /returns
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+####GET####
+Get_return_by_Id_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+
+Get_return_by_Id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+Get_return_by_Id_with_Invalid_return_reference
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find return by the given return reference."
+ And Response should return error code: 3602
+
diff --git a/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/positive.robot
new file mode 100644
index 0000000..3e20c87
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/return_endpoints/returns/positive.robot
@@ -0,0 +1,214 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####POST####
+Create_a_return
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Save value to a variable: [data][id] returnId
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link for created entity: ${returnId}
+
+Create_a_return_include_return_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should not be empty: [included][0][attributes][uuid]
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response body parameter should contain: [included][0][attributes] orderItemUuid
+
+
+#GET####
+Get_lists_of_returns
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return_list
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return_list}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+
+
+Get_lists_of_returns_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return_list_items
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return_list_items}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships] return-items
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] type
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] id
+ And Each array element of array in response should contain nested property with value: [data] [relationships][return-items][data][0][type] return-items
+ And Response include element has self link: return-items
+ And Response include should contain certain entity type: return-items
+ And Response body has correct self link
+
+###GET####
+Get_return_by_Id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=intems {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [data][id] returnId
+
+ When I send a GET request: /returns/${returnReference}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link internal
+
+Get_return_by_Id_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [included][0][attributes][orderItemUuid] orderItemUuid
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnReference}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response body parameter should be: [included][0][attributes][orderItemUuid] ${orderItemUuid}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/negative.robot
new file mode 100644
index 0000000..cd07124
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/negative.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog
+
+*** Test Cases ***
+Search_without_query_parameter
+ When I send a GET request: /catalog-search?
+ Then Response status code should be: 200
diff --git a/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..063ba51
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,708 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product
+
+*** Test Cases ***
+##### SEARCH PARAMETERS #####
+Search_with_empty_search_criteria_all_default_values_check
+ When I send a GET request: /catalog-search?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ #Sorting
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamNames] ${sorting_options.qty}
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamLocalizedNames] ${sorting_options.qty}
+ And Response body parameter should contain: [data][0][attributes] currentSortParam
+ And Response body parameter should contain: [data][0][attributes] currentSortOrder
+ #Pagination
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][pagination][config][validItemsPerPageOptions] 3
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.middle}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.biggest}
+ #Abstract products
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] prices
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.eur.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ #Filters - category
+ And Response body parameter should contain: [data][0][attributes] valueFacets
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][name] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][localizedName] Categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] ${default_qty.categories}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][isMultiValued] False
+ #Filters - labels
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][name] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][localizedName] Label
+ And Response should contain the array larger or equal than a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][isMultiValued] True
+ #Filters - color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][name] color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][localizedName] Color
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] ${default_qty.colors}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][isMultiValued] True
+ #Filters - material
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][name] storage_capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][localizedName] Storage Capacity
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] ${default_qty.storage_capacity}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][config][isMultiValued] True
+ #Filters - brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][name] brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][localizedName] Brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] ${default_qty.brands}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][config][isMultiValued] False
+ #Filters - touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][name] touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][localizedName] Touchscreen
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] ${default_qty.touchscreen}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][config][isMultiValued] False
+ #Filters - weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][name] weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][localizedName] Weight
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][6][values] ${default_qty.weight}
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][config][isMultiValued] True
+ #Filters - price
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][name] price-DEFAULT-EUR-GROSS_MODE
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][localizedName] Price
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][min] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][max] ${default_price.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_price.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][isMultiValued] False
+ #Filters - rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][name] rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][localizedName] Ratings
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][min] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][max] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][config][isMultiValued] False
+ #Filters - category tree
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] nodeId
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] name
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] docCount
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] children
+ #Selflinks
+ And Response body has correct self link
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_by_attribute_that_does_not_return_products
+ When I send a GET request: /catalog-search?q=fake
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 0
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 0
+ And Response body has correct self link
+
+Search_by_concrete_sku
+ When I send a GET request: /catalog-search?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #color
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] 1
+ #storage_capacity
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 1
+ #touchscreen
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 0
+ #weight
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][6][values] 0
+ And Response body has correct self link
+
+Search_by_abstract_sku
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 3
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 6
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #color
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] 2
+ #storage_capacity
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 2
+ #touchscreen
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 0
+ #weight
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][6][values] 1
+ And Response body has correct self link
+
+Search_by_full_name
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 11
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][4][values] 1
+ And Response body has correct self link
+
+Search_by_name_substring
+ When I send a GET request: /catalog-search?q=Lenovo
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 11
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 11
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 1
+ #brand
+ Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 1
+ And Response body has correct self link
+
+Search_by_attribute_(brand)
+ When I send a GET request: /catalog-search?q=${brand_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 43
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 4
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][abstractProducts][0][abstractName] ${brand_4}
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 1
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][values][0][value] ${brand_4}
+ And Response body has correct self link
+
+Search_by_several_attributes
+ When I send a GET request: /catalog-search?q=${color_3}+${aspect_ratio}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 62
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 6
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+
+##### FILTERING #####
+
+Filter_by_rating_only_min
+ When I send a GET request: /catalog-search?q=&rating[min]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 6
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 6
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.max}
+
+
+Filter_by_rating_only_max
+ When I send a GET request: /catalog-search?q=rating[max]=${default_rating.min}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 19
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 2
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.min}
+
+
+Filter_by_rating_Min_max
+ When I send a GET request: /catalog-search?q=&rating[min]=3&rating[max]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] 3
+
+Filter_by_price_only_min
+ When I send a GET request: /catalog-search?q=&price[min]=1000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 3
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 100000
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_price.max}
+
+Filter_by_price_only_max
+ When I send a GET request: /catalog-search?q=&price[max]=3000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 213
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 18
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 300000
+
+Filter_by_price_Min_max
+ When I send a GET request: /catalog-search?q=&price[min]=1000&price[max]=3000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 100000
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 300000
+
+Filter_by_brand_one_brand
+ When I send a GET request: /catalog-search?q=&brand=${brand_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 43
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${brand_4}
+ And Response body has correct self link
+
+Filter_by_brand_two_brands
+ When I send a GET request: /catalog-search?q=&brand[]=${brand_4}&brand[]=${brand_5}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 54
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 5
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][0] ${brand_4}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][1] ${brand_5}
+
+Filter_by_brand_empty_brand
+ When I send a GET request: /catalog-search?q=&brand=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${EMPTY}
+ And Response body has correct self link
+
+Filter_by_brand_non_existing_brand
+ When I send a GET request: /catalog-search?q=&brand=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] test123
+ And Response body has correct self link
+
+Filter_by_label_one_label
+ When I send a GET request: /catalog-search?q=&label=${label.new}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 7
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 7
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] ${label.new}
+ And Response body has correct self link
+
+Filter_by_label_two_labels
+ When I send a GET request: /catalog-search?q=&label[]=${label.new}&label[]=${label.sale}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 67
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${label.new}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][1] ${label.sale}
+
+Filter_by_label_non_existing_label
+ When I send a GET request: /catalog-search?q=&label[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] test123
+
+Filter_by_label_empty_label
+ When I send a GET request: /catalog-search?q=&label[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${EMPTY}
+
+Filter_by_color_one_color
+ When I send a GET request: /catalog-search?q=&color=${color_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 75
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 7
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] ${color_4}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][0] ${default_qty.categories}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][2] ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_color_two_colors
+ When I send a GET request: /catalog-search?q=&color[]=${color_2}&color[]=${color_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 86
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 8
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${color_2}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][1] ${color_4}
+
+Filter_by_color_non_existing_color
+ When I send a GET request: /catalog-search?q=&color[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] test123
+
+Filter_by_color_empty_color
+ When I send a GET request: /catalog-search?q=&color[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${EMPTY}
+
+Filter_by_valid_main_category
+ When I send a GET request: /catalog-search?q=&category=${category_lvl1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl1.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl1.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Array element should contain property with value at least once: [data][0][attributes][categoryTreeFilter] docCount ${${category_lvl1.qty}}
+ And Response body has correct self link
+
+Filter_by_valid_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl2.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl2.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Array element should contain property with value at least once: [data][0][attributes][categoryTreeFilter] docCount ${${category_lvl2.qty}}
+ And Response body has correct self link
+
+Search_with_specific_currency
+ When I send a GET request: /catalog-search?q=¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_CHF}
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.chf.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+#### PAGINATION AND SORTING #####
+
+Search_set_specific_page_with_default_ipp
+ # here page 4 is selected using offset because 36/12=3 full pages, search shows the next page after the offset
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.default}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 4
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Search_set_specific_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.middle}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 2
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 9
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.middle}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_last_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.biggest}&page[offset]=${total_number_of_products_in_search}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 6
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 6
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+
+Search_set_invalid_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=18&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_sort_by_name_asc
+ When I send a GET request: /catalog-search?q=&sort=name_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] A
+ And Response body has correct self link
+
+Search_sort_by_name_desc
+ When I send a GET request: /catalog-search?q=&sort=name_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] Toshiba
+ And Response body has correct self link
+
+Search_sort_by_rating
+ When I send a GET request: /catalog-search?q=&sort=rating
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] rating
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_sku_highest_rating}
+ And Response body has correct self link
+
+
+Search_sort_by_price_asc
+ When I send a GET request: /catalog-search?q=&sort=price_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1800
+ And Response body has correct self link
+
+Search_sort_by_price_desc
+ When I send a GET request: /catalog-search?q=&sort=price_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10000
+ And Response body has correct self link
+
+Search_sort_by_price_filter_query_parameter_and_pagination
+ When I send a GET request: /catalog-search?q=son&sort=price_desc&brand=${brand_4}&page[limit]=${ipp.middle}&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 43
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 2
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 24
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${brand_4}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] 345699
+
+Search_by_abstract_sku_with_abstract_include
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractName] ${abstract_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-products][data] 3
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][2][id] ${abstract_product_with_alternative.sku}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/negative.robot
new file mode 100644
index 0000000..7212837
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/negative.robot
@@ -0,0 +1,66 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### use Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+Get_health_check_with_disabled_services
+### Test works only if all services are disabled as default
+ When I send a GET request: /health-check
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 403
+ And Response body parameter should be: [data][0][attributes][message] HealthCheck endpoints are disabled for all applications.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_invalid_service_name
+ When I send a GET request: /health-check?services=sear
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_empty_service_name
+ When I send a GET request: /health-check?services=
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+#Get_health_check_with_non_existing_id
+## The bug https://spryker.atlassian.net/browse/CC-16492 related to the self link and required ID
+ # When I send a GET request: /health-check/1
+ # Then Response status code should be: 200
+ # And Response reason should be: OK
+ # And Response body parameter should be: [data][type] health-check
+ # And Response body parameter should be: [data][id] None
+ # And Response body parameter should be: [data][attributes][status] healthy
+ # And Response body parameter should be: [data][attributes][statusCode] 200
+ # And Response body parameter should be: [data][attributes][message] None
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][0][name] search
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][1][name] storage
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][2][name] zed-request
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] status True
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] message None
+ ## Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/positive.robot
new file mode 100644
index 0000000..de2262d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/health_checks/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+#Get_health_check_with_all_enabled_services
+ #When I send a GET request: /health-check
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 3
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][1][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][2][name] zed-request
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] status True
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] message None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_search_service
+ #When I send a GET request: /health-check?services=search
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_storage_service
+ #When I send a GET request: /health-check?services=storage
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_zed_request_service
+ #When I send a GET request: /health-check?services=zed-request
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] zed-request
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..e95e627
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/negative.robot
@@ -0,0 +1,12 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response should return error code: 601
+ And Response should return error message: Store not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..fba4cfb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/stores/positive.robot
@@ -0,0 +1,117 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+#get
+Get_all_available_stores
+ [Tags] dms-off
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] timeZone
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] code
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_all_available_stores_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ [Tags] dms-off
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should have datatype: [data][attributes][timeZone] str
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][locales] code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
+
+Get_store_by_id_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/negative.robot
new file mode 100644
index 0000000..04e4f0d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/negative.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_url_collection_by_empty_url
+ When I send a GET request: /url-resolver
+ Then Response status code should be: 422
+ And Response should return error code: 2801
+ And Response should return error message: Url request parameter is missing.
+
+Get_url_collection_when_requested_url_does_not_exist
+ When I send a GET request: /url-resolver?url=/requested/url/does/not/exist/
+ Then Response status code should be: 404
+ And Response should return error code: 2802
+ And Response should return error message: Url not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/positive.robot
new file mode 100644
index 0000000..136cfef
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/utility_endpoints/url_resolver/positive.robot
@@ -0,0 +1,53 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_url_collections_by_url_paramater_of_category_nodes
+ When I send a GET request: /url-resolver?url=${url_resolver_category_nodes}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_category_nodes_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_category_nodes_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_product
+ When I send a GET request: /url-resolver?url=${url_resolver_abstract_product}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_product_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_product_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_cms_page
+ When I send a GET request: /url-resolver?url=${url_resolver_cms}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_cms_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_cms_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_parameters_returns_id
+ [Documentation] CC-16595 API: ID is missing from url resolver.
+ [Tags] skip-due-to-issue
+ When I send a GET request: /url-resolver?url=${url_resolver_category_nodes}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ When I send a GET request: /url-resolver?url=${url_resolver_abstract_product}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ When I send a GET request: /url-resolver?url=${url_resolver_cms}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/negative.robot
new file mode 100644
index 0000000..16901fd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/negative.robot
@@ -0,0 +1,500 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue wishlist product configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+#Post
+Adding_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Adding_item_in_wishlist_by_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Adding_item_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.sku}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "SK123445666"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_after_enter_space_in_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": " "}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_wishlist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/Mywishlist/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+
+Adding_item_without_wishlist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists//wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Adding_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+# There is no demo data for this test case
+Adding_item_with_deactivated_item_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "Demo-SKU-Id"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Deleting_item_in_wishlist_by_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Deleting_item_in_wishlist_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Deleting_item_after_enter_space_in_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/" "
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 208
+ And Response should return error message: No item with provided sku in wishlist.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Deleting_item_which_is_not_exist_in_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 208
+ And Response should return error message: No item with provided sku in wishlist.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Delete_wishlist_item_from_already_deleted_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_with_invalid_wishlist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/Mywishlist/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_without_wishlist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists//wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Deleting_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_item_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${wishlist_item_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Deleting_concrete_product_by_abstract_product_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.sku}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 208
+ And Response should return error message: No item with provided sku in wishlist.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration_and_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_item_id2
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [included][1][id] ${ wishlist_item_id2}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_availableQuantity_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-30918
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":-1,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should be greater than 0."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should not be blank."
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_configurable_product_with_missing_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This field is missing."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"test","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":1,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":"True","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be of type numeric.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_wishlist_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/positive.robot
new file mode 100644
index 0000000..3dec3ad
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlist_items/positive.robot
@@ -0,0 +1,385 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue wishlist product prices configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+#Post
+
+Adding_item_in_wishlist
+ [Documentation] #CC-16555 API: JSON response is missing product availability and price
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And Response body parameter should be: [data][type] wishlist-items
+ And Response body parameter should be: [data][id] ${wishlist_items_id}
+ And Response body parameter should be: [data][attributes][sku] ${product_availability.concrete_available_product_with_stock}
+ And Response body parameter should be: [data][attributes][id] ${wishlist_items_id}
+ And Response body parameter should not be EMPTY: [data][attributes][availability]
+ And Response body parameter should not be EMPTY: [data][attributes][price]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Adding_multiple_variant_of_abstract_product_in_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${multivariant.concrete_product.sku_variant1}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${multivariant.concrete_product.sku_variant2}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][1]
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_from_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${product_availability.concrete_available_product_with_stock}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+
+Add_a_configurable_product_with_first_product_variant_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][type] wishlist-items
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][id] ${configurable_product.sku_1}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be: [included][1][id] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_second_product_variant_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][type] wishlist-items
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][id] ${configurable_product.sku_2}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be: [included][1][id] ${configurable_product.sku_2}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"10.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"10.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.11.2029\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.12.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId2
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 4
+ And Response body parameter should be in: [included][0][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][0][id] ${WishListItemId2} ${wishlist_id} ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][1][id] ${WishListItemId2} ${wishlist_id} ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response body parameter should be in: [included][2][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][2][id] ${WishListItemId2} ${wishlist_id} ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][3][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][3][id] ${WishListItemId2} ${wishlist_id} ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][3][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][3][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be in: [included][3][attributes][productConfigurationInstance][isComplete] True False
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_product_variant_of_Configurable_products_without_configurations_and_set_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.12.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId2
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be: [included][0][type] wishlist-items
+ And Response body parameter should be in: [included][0][id] ${configurable_product.sku_1} ${configurable_product.sku_2} ${WishListItemId2}
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2} ${WishListItemId2}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be in: [included][1][id] ${WishListItemId2} ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2} ${WishListItemId2}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: wishlist-items
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId2}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${product_availability.concrete_available_product_with_stock}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${configurable_product.sku_1} ${product_availability.concrete_available_product_with_stock}
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku_1} ${product_availability.concrete_available_product_with_stock}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] displayData {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] isComplete True
+ And Response body parameter should be in: [included][1][id] ${configurable_product.sku_1} ${product_availability.concrete_available_product_with_stock}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_1} ${product_availability.concrete_available_product_with_stock}
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId1
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${product_availability.concrete_available_product_with_stock}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${product_availability.concrete_available_product_with_stock}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${product_availability.concrete_available_product_with_stock}
+ And Response body parameter should be: [included][0][attributes][sku] ${product_availability.concrete_available_product_with_stock}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/negative.robot b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/negative.robot
new file mode 100644
index 0000000..4440482
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/negative.robot
@@ -0,0 +1,169 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+#Get_request
+Getting_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /wishlists
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Getting_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /wishlists
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Getting_wishlist_with_invalid_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /wishlists/2345hasd
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+
+######POST#####
+Creating_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+
+Creating_wishlist_with_space_in_name
+ [Documentation] Post Request https://spryker.atlassian.net/browse/CC-16553
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name":" "}}}
+ Then Response status code should be: 400
+ And Response should return error message: Please enter name using only letters, numbers, underscores, spaces or dashes.
+ And Response should return error code: 210
+
+Creating_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Creating_wishlist_with_missing_name
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+
+Creating_wishlist_with_invalid_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "."}}}
+ Then Response status code should be: 400
+ And Response should return error message: Please enter name using only letters, numbers, underscores, spaces or dashes.
+ And Response should return error code: 210
+
+Creating_Wishlist_with_a_name_that_already_exists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ AND Response should return error code: 202
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Delete_already_deleted_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a DELETE request: /wishlists
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Deleting_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a Delete request: /wishlists/123
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Deleting_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a Delete request: /wishlists/123
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+#Delete_request
+Wishlist_id_not_specified
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a DELETE request: /wishlists/
+ Then Response reason should be: Bad Request
+ And Response status code should be: 400
+
+#Patch_request
+Updating_wishlist_with_missing_name
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ When I send a Patch request: /wishlists/${wishlist_id} {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ Then Response status code should be: ${422}
+ AND Response reason should be: Unprocessable Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Updating_wishlist_with_invalid_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ When I send a Patch request: /wishlists/${wishlist_id} {"data": {"type": "wishlists","attributes": {"name": "."}}}
+ Then Response status code should be: ${422}
+ And Response should return error message: Please enter name using only letters, numbers, underscores, spaces or dashes.
+ And Response should return error code: 210
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Updating_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a Patch request: /wishlists/123 {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Updating_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a Patch request: /wishlists/123 {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
diff --git a/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/positive.robot b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/positive.robot
new file mode 100644
index 0000000..c20fcbd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/glue/wishlist_endpoints/wishlists/positive.robot
@@ -0,0 +1,163 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+#GET Request
+Retrieves_all_customer_wishlists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a GET request: /wishlists
+ Then Response status code should be: 200
+ AND Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type wishlists
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] numberOfItems
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+
+#GET Request
+Retrieves_wishlist_data_by_id
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response body parameter should be: [data][type] wishlists
+ AND Save value to a variable: [data][attributes][name] wishlist_name
+ AND Save value to a variable: [data][id] wishlist_id
+ AND Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ AND Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ AND Response body parameter should not be EMPTY: [data][id]
+ AND Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ AND Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Get_Request
+Retrieves_wishlist_with_items
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Get Request
+Retrieves_wishlist_with_items_in_concrete
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Get Request
+Wishlist_Product_Labels
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products,product-labels
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: product-labels
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Post Request
+Creates_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ And Save value to a variable: [data][id] wishlist_del_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][id] ${wishlist_del_id}
+ AND Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ AND Response body parameter should be: [data][type] wishlists
+ AND Response body parameter should be: [data][attributes][numberOfItems] 0
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_del_id}
+ ... AND Response status code should be: 204
+
+#Patch Request
+Updates_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a PATCH request: /wishlists/${wishlist_id} {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ AND Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ AND Response body parameter should be: [data][type] wishlists
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+# Delete Request
+Removes_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlists_id
+ When I send a DELETE request: /wishlists/${wishlists_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /wishlists/${wishlists_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..6da845a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found
diff --git a/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..4ff5077
--- /dev/null
+++ b/atest/testdata/performance/tests/api/b2c/sapi/utility_endpoints/stores/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_all_available_stores
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/negative.robot
new file mode 100644
index 0000000..d4086b6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/negative.robot
@@ -0,0 +1,396 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_product_abstract_collection_with_invalid_query_parameter:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=test
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+
+Create_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH INVALID CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_correct_child_and_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}, {"fk_tax_set": 1, "attributes": "FOO1", "sku": "FOO1", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR1", "sku": "FOOBAR1"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ And Response body parameter should be: [data][0][sku] FOO1
+ And Response body parameter should be: [data][0][attributes] FOO1
+ ### GET PRODUCT ABSTRACT WITH CHILDREN ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] FOO1
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][id_product] ${id_product}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1310
+ And Response body parameter should be: [0][message] Incomplete Request - missing identifier for `robot-tests-product-abstracts0.robot-tests-products0`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1309
+ And Response body parameter should be: [0][message] Failed to persist the data for `robot-tests-product-abstracts0.robot-tests-products0.sku`. Please verify the provided data and try again. Entry is duplicated.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_country_collection_with_existing_child_entity
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_product_abstract_by_id_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST PRODUCT ABSTRACT ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_product_abstract_collection_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_price_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
diff --git a/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/positive.robot
new file mode 100644
index 0000000..9c78788
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/complex/positive.robot
@@ -0,0 +1,348 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+ Get_product_abstract_collection_with_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Delete dynamic entity configuration in Database: robot-tests-product-prices
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ Trigger p&s
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 416
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Each array element of array in response should contain property: [data] id_product_abstract
+ And Each array element of array in response should contain property: [data] sku
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] id_product
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] fk_product_abstract
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 416
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Get_product_abstract_with_childs_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 1
+ And Response body parameter should be: [data][id_product_abstract] 130
+ And Response body parameter should be: [data][sku] M21714
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] 130
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Create_and_update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Create_product_abstract_collection_with_two_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH TWO CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}], "robotTestsProductPrices": [{"fk_price_type": 1, "price": 0}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO2
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR2
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ When Save value to a variable: [data][0][robotTestsProductPrices][0][id_price_product] id_price_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][0][robotTestsProductPrices][0][fk_product_abstract] ${id_product_abstract}
+
+ [Teardown] Run Keywords Delete product_price by id_price_product in Database: ${id_price_product}
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Upsert_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract},"attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][approval_status] None
+ And Response body parameter should be: [data][0][new_to] None
+ And Response body parameter should be: [data][0][color_code] None
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_publish_complex_product_with_child_relations:
+ [Documentation] As the tech dept, we need to adjust this test to check in /catalog-search as well.
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-stock-products spy_stock_product 1 {"identifier":"id_stock_product","fields":[{"fieldName":"id_stock_product","fieldVisibleName":"id_stock_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"quantity","fieldVisibleName":"quantity","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_never_out_of_stock","fieldVisibleName":"is_never_out_of_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_stock","fieldVisibleName":"fk_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-localized-attributes spy_product_localized_attributes 1 {"identifier":"id_product_attributes","fields":[{"fieldName":"id_product_attributes","fieldVisibleName":"id_product_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-stores spy_product_abstract_store 1 {"identifier":"id_product_abstract_store","fields":[{"fieldName":"id_product_abstract_store","fieldVisibleName":"id_product_abstract_store","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relations spy_product_relation 1 {"identifier":"id_product_relation","fields":[{"fieldName":"id_product_relation","fieldVisibleName":"id_product_relation","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_relation_type","fieldVisibleName":"fk_product_relation_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_rebuild_scheduled","fieldVisibleName":"is_rebuild_scheduled","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"product_relation_key","fieldVisibleName":"product_relation_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"query_set_data","fieldVisibleName":"query_set_data","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relation-stores spy_product_relation_store 1 {"identifier":"id_product_relation_store","fields":[{"fieldName":"id_product_relation_store","fieldVisibleName":"id_product_relation_store","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_relation","fieldVisibleName":"fk_product_relation","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-products spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-stores spy_price_product_store 1 {"identifier":"id_price_product_store","fields":[{"fieldName":"id_price_product_store","fieldVisibleName":"id_price_product_store","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_currency","fieldVisibleName":"fk_currency","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_price_product","fieldVisibleName":"fk_price_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"gross_price","fieldVisibleName":"gross_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"net_price","fieldVisibleName":"net_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-defaults spy_price_product_default 1 {"identifier":"id_price_product_default","fields":[{"fieldName":"id_price_product_default","fieldVisibleName":"id_price_product_default","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_product_store","fieldVisibleName":"fk_price_product_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-label-product-abstracts spy_product_label_product_abstract 1 {"identifier":"id_product_label_product_abstract","fields":[{"fieldName":"id_product_label_product_abstract","fieldVisibleName":"id_product_label_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_label","fieldVisibleName":"fk_product_label","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-image-sets spy_product_image_set 1 {"identifier":"id_product_image_set","fields":[{"fieldName":"id_product_image_set","fieldVisibleName":"id_product_image_set","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-stores robotTestsProductAbstractStores fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-relations robotTestsProductRelations fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-relations robot-tests-product-relation-stores robotTestsProductRelationStores fk_product_relation id_product_relation
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-price-products robotTestsProductAbstractPriceProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-price-products robot-tests-price-product-stores robotTestsPriceProductStores fk_price_product id_price_product
+ Create dynamic entity configuration relation in Database: robot-tests-price-product-stores robot-tests-price-product-defaults robotTestsPriceProductStoreDefaults fk_price_product_store id_price_product_store
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-categories robotTestsProductAbstractCategories fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-label-product-abstracts robotTestsProductLabelProductAbstracts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-image-sets robotTestsProductImageSets fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-searches robotTestsProductSearch fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-stock-products robotTestsProductStocks fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-localized-attributes robotTestsProductLocalizedAttributes fk_product id_product
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH STOCK ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":2,"approval_status":"approved","attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec","color_code":"#DC2E09","robotTestsProductAbstractProducts":[{"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1 test attributes","is_active":1,"is_quantity_splittable":1,"sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","robotTestsProductSearch":[{"fk_locale":66,"is_searchable":1}, {"fk_locale":46,"is_searchable":1}],"robotTestsProductStocks":[{"fk_stock":1,"is_never_out_of_stock":1,"quantity":10}],"robotTestsProductLocalizedAttributes":[{"fk_locale":66,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}],"robotTestsProductAbstractStores":[{"fk_store":1}],"robotTestsProductRelations":[{"fk_product_relation_type":1,"is_active":1,"is_rebuild_scheduled":1,"product_relation_key":"Prk-d04e93a4-29ea-4c48-96ab-e87416aefbec","query_set_data":"","robotTestsProductRelationStores":[{"fk_store":1}]}],"robotTestsProductAbstractPriceProducts":[{"fk_price_type":1,"price":1000,"robotTestsPriceProductStores":[{"fk_currency":93,"fk_store":1,"gross_price":9999,"net_price":8999,"robotTestsPriceProductStoreDefaults":[{}]}]}],"robotTestsProductAbstractCategories":[{"fk_category":5,"product_order":16}],"robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"},{"fk_locale":46,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"}],"robotTestsProductLabelProductAbstracts":[{"fk_product_label":1}],"robotTestsProductImageSets":[{"fk_locale":66,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}]}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Save value to a variable: [data][0][sku] abstract_sku
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][sku] concrete_sku
+ Trigger p&s
+ Trigger p&s
+ Trigger p&s
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /abstract-products/${abstract_sku}/abstract-product-availabilities
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] d04e93a4-29ea-4c48-96ab-e87416aefbec
+
+ I set Headers: Content-Type=application/vnd.api+json Accept=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /concrete-products/${concrete_sku}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ And Response body parameter should be: [data][attributes][sku] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-searches?filter[product-searches.fk_product]=${id_product}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][0][id_product_search] id_product_search_first
+ And Save value to a variable: [data][1][id_product_search] id_product_search_second
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-searches {"data": [{"id_product_search": ${id_product_search_first},"is_searchable": 0}, {"id_product_search": ${id_product_search_second},"is_searchable": 0}]}
+ Then Response status code should be: 200
+ Trigger p&s
+ Trigger p&s
+ [Teardown] Run Keywords Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductSearch
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductStocks
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductImageSets
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLabelProductAbstracts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractCategories
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStoreDefaults
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractPriceProducts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelationStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelations
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-image-sets
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-label-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-categories
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-defaults
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relation-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relations
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
+ ... AND Delete dynamic entity configuration in Database: robot-tests-stock-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
diff --git a/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/negative.robot
new file mode 100644
index 0000000..189c3a1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/negative.robot
@@ -0,0 +1,451 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_list_of_country_with_invalid_token
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID TOKEN ###
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_prefix
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE PREFIX ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity-invalid/robot-test-countries
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE NAME ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/invalid-resource
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/countries/9999999
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_body
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY BODY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_json
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY JSON ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {"data": []}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_valid_and_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}, {"iso2_code":"XX", "iso3_code":"XXX", "name":"Country XXX"}]}
+ Then Response status code should be: 201
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ And Response body parameter should contain: [data][0][iso2_code] XX
+ And Response body parameter should contain: [data][0][iso3_code] XXX
+ When Save value to a variable: [data][0][id_country] country_id
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID RESOURCE NAME ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/cnt {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 404
+ And Response body parameter should contain: [0][message] Not found
+ And Response body parameter should be: [0][code] 007
+ And Response body parameter should contain: [0][status] 404
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_field_value
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID FIELD VALUE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"X","iso3_code":"XXXX","name":""}]}
+ Then Response status code should be: 400
+ And Response should contain the array of a certain size: $ 3
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should contain: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries0` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should contain: [1][status] 400
+ And Response body parameter should contain: [2][message] Invalid data value `robot-test-countries0` for field: `name`.
+ And Response body parameter should be: [2][code] 1306
+ And Response body parameter should contain: [2][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: X
+
+Create_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url", "fk_locale": 46}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] XXA
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] XXB
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XXXX"}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_collection_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY COLLECTION WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XXXX"},{"id_country":${xxb_country_id},"iso3_code":"XXXXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries1` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should be: [1][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field_type
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID FILELD TYPE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name": "FOO", "iso2_code":1234, "iso3_code": 1234}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data type `robot-test-countries0` for field `iso2_code`
+ And Response body parameter should be: [0][code] 1305
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Upsert_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### UDATE WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/1000 {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Entity `robot-test-countries0.id_country: 1000` not found by identifier, and new identifier can not be persisted. Please update the request.
+ And Response body parameter should be: [0][code] 1308
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Delete_country_by_id_is_deletable_false:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": false,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_is_deletable_null:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": null,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_without_is_deletable:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
diff --git a/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/positive.robot
new file mode 100644
index 0000000..5793370
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/bapi/dynamic_entity/positive.robot
@@ -0,0 +1,579 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/api_dynamic_entity_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_country_collection
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 6
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] iso3_code ZMB
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_Collection_with_filter_first_item
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER FIRST ITEM ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=AC
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=UA
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_multiple_filter_fields
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}&filter[countries.postal_code_mandatory]=1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter_in_condition
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code AE
+ And Array in response should contain property with value: [data] iso3_code ARE
+ And Array in response should contain property with value: [data] name United Arab Emirates
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_invalid_multiple_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"], "not in": ["AT"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=234&page[limit]=2
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property: [data] iso2_code
+ And Each array element of array in response should contain property: [data] iso3_code
+ And Each array element of array in response should contain property: [data] name
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations_out_of_items
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS OUT OF ITEMS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=500&page[limit]=10
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+
+Get_country_collection_with_short_configuration
+ ### SETUP DYNAMIC ENTITY CONFIGURATION WITH LESS NUMBER OF FIELDS ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH SHORT CONFIGURATION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 3
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_by_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request with data: /token 'grantType=password&username=admin@spryker.com&password=change123'
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+ When Save value to a variable: [access_token] token
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should not be EMPTY: [data][iso2_code]
+ And Response body parameter should not be EMPTY: [data][iso3_code]
+ And Response body parameter should not be EMPTY: [data][name]
+ And Response body parameter should not be EMPTY: [data][postal_code_mandatory]
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_and_update_country:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XM
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XM","iso3_code":"XXM","name":"POST XM"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XM
+ And Response body parameter should be: [data][0][iso3_code] XXM
+ And Response body parameter should be: [data][0][name] POST XM
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ ### UPDATE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ ### UPDATE ONE FIELD OF COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name":"Test Country"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Test Country
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Test Country
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XM
+
+Create_and_update_url:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST URL AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: /test-url/123
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"/test-url/123", "fk_locale": 46}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][url] /test-url/123
+ And Response body parameter should be: [data][0][fk_locale] 46
+ When Save value to a variable: [data][0][id_url] id_url
+ ### UPDATE URL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls/${id_url} {"data":{"url":"/test-url-test/42"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ And Response body parameter should be: [data][id_url] ${id_url}
+ ### GET URL AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-urls/${id_url}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: /test-url-test/42
+
+Create_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Create_country_collection_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Upsert_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ Delete country by iso2_code in Database: XL
+ Delete country by iso2_code in Database: XS
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XAA","name":"PUT XAA"},{"iso2_code":"XB","iso3_code":"XBB","name":"PUT XBB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] PUT XAA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] PUT XBB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ When Save value to a variable: [data][0][id_country] xaa_country_id
+ When Save value to a variable: [data][1][id_country] xbb_country_id
+
+ ## UPSERT ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ ### PARTIAL UPDATE ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXL"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Country XXL
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXL
+ ### UPSERT COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xaa_country_id},"iso2_code":"XL","iso3_code":"XXL","name":"XXL"},{"id_country":${xbb_country_id},"iso2_code":"XS","iso3_code":"XXS","name":"XXS"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XL
+ And Response body parameter should be: [data][0][iso3_code] XXL
+ And Response body parameter should be: [data][0][name] XXL
+ And Response body parameter should be: [data][0][id_country] ${xaa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XS
+ And Response body parameter should be: [data][1][iso3_code] XXS
+ And Response body parameter should be: [data][1][name] XXS
+ And Response body parameter should be: [data][1][id_country] ${xbb_country_id}
+ ### GET COUNTRIES AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XL
+ And Response body parameter should be: [data][iso3_code] XXL
+ And Response body parameter should be: [data][name] XXL
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xbb_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XS
+ And Response body parameter should be: [data][iso3_code] XXS
+ And Response body parameter should be: [data][name] XXS
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XL
+ ... AND Delete country by iso2_code in Database: XS
+
+Delete_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_country_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][0][iso2_code] XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_id
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] ${xxa_iso2_code}
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `robot-test-countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Authorization_by_x_api_key
+ [Documentation] data excahnge api should support 2 autorization options: by x-api-key and by backoffice user token.
+ [Setup] Create api key in db
+ When I set Headers: x-api-key=${dummy_api_key}
+ And I send a GET request: /dynamic-entity/categories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ [Teardown] Delete api key from db
+
+Availability_recalculation_after_stock_update
+ [Documentation] checks that product availability is recalculated after stock update via data exchange api
+ [Setup] Find first available product via data exchange api
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/stock-products/${index} {"data":{"is_never_out_of_stock":false,"quantity":0}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][is_never_out_of_stock] False
+ And Response body parameter should be: [data][quantity] 0
+ Trigger p&s
+ And Product availability status should be changed on: is_available=False
+ [Teardown] Run Keywords Remove Tags *
+ ... AND Set Tags bapi
+ ... AND Restore product initial stock via data exchange api:
diff --git a/atest/testdata/performance/tests/api/mp_b2b/dynamic_store/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/dynamic_store/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..324eed5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/dynamic_store/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue
+
+
+*** Test Cases ***
+
+# SEARCH PARAMETERS #
+
+
+Search_by_abstract_sku_per_store
+ [Tags] dms-on
+ When I set Headers: store=DE
+ Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${abstract_available_product_with_stock.price_de}
+ When I set Headers: store=AT
+ Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${abstract_available_product_with_stock.price_at}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
new file mode 100644
index 0000000..2ad9825
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Get_alternative_abstract_with_nonexistant_SKU
+ When I send a GET request: /concrete-products/fake/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_with_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_without_SKU
+ When I send a GET request: /concrete-products//abstract-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
new file mode 100644
index 0000000..0a373d9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Product_has_abstract_alternative
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body parameter should have datatype: [data][0][attributes][name] str
+ And Response body parameter should be in: [data][0][attributes][sku] ${concrete_product_with_alternative.abstract_sku} M770 M788
+ And Response body parameter should be in: [data][1][attributes][sku] ${concrete_product_with_alternative.abstract_sku} M770 M788
+ And Response body parameter should be in: [data][2][attributes][sku] ${concrete_product_with_alternative.abstract_sku} M770 M788
+ And Response body has correct self link
+
+Product_has_abstract_alternative_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}/abstract-alternative-products?include=abstract-product-image-sets,abstract-product-availabilities,abstract-product-prices,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body has correct self link
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: abstract-product-prices
+
+Product_has_no_abstract_alternative
+ When I send a GET request: /concrete-products/${product_with_relations.has_related_products.concrete_sku}/abstract-alternative-products
+ Then Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ And Response reason should be: OK
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
new file mode 100644
index 0000000..bb48624
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_abstract_availability_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_alternative.sku}/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
new file mode 100644
index 0000000..0059554
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Product_is_available_with_stock_and_never_out_of_stock
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.product_3.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_availability.product_3.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_with_stock
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_never_out_of_stock
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
+
+Product_is_unavailable
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.abstract_unavailable_product}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_availability.abstract_unavailable_product}
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_available_with_3_concrete_stocks_combined
+ #checks that stock of all 3 concretes as aggregated in response
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
new file mode 100644
index 0000000..9bb5b11
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_image_sets_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_alternative.sku}/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
new file mode 100644
index 0000000..ec92b79
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
@@ -0,0 +1,77 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_abstract_image_sets_with_1_concrete
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][type] abstract-product-image-sets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body has correct self link
+
+Get_abstract_image_sets_with_3_concretes
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body has correct self link
+
+
+Get_abstract_product_with_1_concrete_with_include_abstract_product_image_sets
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}?include=abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][abstract-product-image-sets][data][0][type] abstract-product-image-sets
+ And Response body parameter should be: [data][relationships][abstract-product-image-sets][data][0][id] ${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][id] ${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type abstract-product-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes imageSets
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] name
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] images
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlLarge
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlSmall
+ And Response body has correct self link internal
+
+
+Get_abstract_product_with_3_concretes_with_include_abstract_product_image_sets
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}?include=abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should contain: [data][relationships] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-image-sets][data] type
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-image-sets][data] id
+ And Response body parameter should be: [included][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type abstract-product-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes imageSets
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] name
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] images
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlLarge
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlSmall
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
new file mode 100644
index 0000000..6330a0c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
@@ -0,0 +1,48 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_prices_by_concrete_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${concrete_product_with_alternative.sku}/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_by_fake_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/fake/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_with_missing_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products//abstract-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_abstract_prices_with_missing_token
+ When I send a GET request: /abstract-products/${abstract_product.product_with_original_prices.abstract_sku}/abstract-product-prices
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_abstract_prices_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=fake
+ When I send a GET request: /abstract-products/${abstract_product.product_with_original_prices.abstract_sku}/abstract-product-prices
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
new file mode 100644
index 0000000..3096b8f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
@@ -0,0 +1,155 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_prices_detault_only
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][0][type] abstract-product-prices
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+
+Get_abstract_prices_detault_only_CHF
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}/abstract-product-prices?currency=CHF&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][0][type] abstract-product-prices
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Get_abstract_product_with_include_abstract_product_prices_only_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_variants.concretes_3}?include=abstract-product-prices¤cy=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][relationships][abstract-product-prices][data][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][relationships][abstract-product-prices][data][0][type] abstract-product-prices
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-prices][data] type
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-prices][data] id
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response include should contain certain entity type: abstract-product-prices
+ And Each array element of array in response should contain property with value: [included] type abstract-product-prices
+ And Response body parameter should be: [included][0][id] ${abstract_product.abstract_product_with_variants.concretes_3}
+ And Each array element of array in response should contain nested property: [included] attributes price
+ And Each array element of array in response should contain nested property: [included] attributes prices
+ And Each array element of array in response should contain nested property: [included] [attributes][prices] priceTypeName
+ And Response body parameter should be: [included][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_abstract_product_volume_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.product_with_volume_prices.abstract_sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_volume_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][grossAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][netAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][quantity] 1
+ And Response body has correct self link
+
+Get_abstract_product_with_include_abstract_product_prices_with_volume_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.product_with_volume_prices.abstract_sku}?include=abstract-product-prices¤cy=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_volume_prices.abstract_sku}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should be: [data][relationships][abstract-product-prices][data][0][id] ${abstract_product.product_with_volume_prices.abstract_sku}
+ And Response body parameter should be: [data][relationships][abstract-product-prices][data][0][type] abstract-product-prices
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-prices][data] type
+ And Each array element of array in response should contain property: [data][relationships][abstract-product-prices][data] id
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type abstract-product-prices
+ And Each array element of array in response should contain nested property: [included] attributes price
+ And Each array element of array in response should contain nested property: [included] attributes prices
+ And Each array element of array in response should contain nested property: [included] [attributes][prices] priceTypeName
+ And Each array element of array in response should contain nested property: [included] [attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain nested property: [included] [attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain nested property: [included] [attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be: [included][0][id] ${abstract_product.product_with_volume_prices.abstract_sku}
+ And Response body parameter should be: [included][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_abstract_product_with_original_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.product_with_original_prices.abstract_sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_original_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than: [data][0][attributes][prices][1][grossAmount] ${default_price}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${NONE}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.code}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.name}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.symbol}
+ ${list} = Create List
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${list}
+ And Response body has correct self link
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/negative.robot
new file mode 100755
index 0000000..2eef3e7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_product_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_alternative.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_by_fake_SKU
+ When I send a GET request: /abstract-products/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_with_missing_SKU
+ When I send a GET request: /abstract-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/positive.robot
new file mode 100755
index 0000000..55f8aa0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/abstract_product_endpoints/abstract_products/positive.robot
@@ -0,0 +1,220 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product tax product-labels product-options inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_abstract_product_with_one_concrete
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][merchantReference] ${abstract_available_product_with_stock.merchant_reference}
+ And Response body parameter should have datatype: [data][attributes][reviewCount] int
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][attributes][description] ${abstract_available_product_with_stock.description}
+ And Response body parameter should be: [data][attributes][metaTitle] ${abstract_available_product_with_stock.meta_title}
+ And Response body parameter should be: [data][attributes][metaKeywords] ${abstract_available_product_with_stock.meta_keywords}
+ And Response body parameter should be: [data][attributes][metaDescription] ${abstract_available_product_with_stock.meta_description}
+ And Response body parameter should be: [data][attributes][attributeMap][product_concrete_ids][0] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response should contain the array of a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 1
+ And Response body parameter should have datatype: [data][attributes][attributeMap][attribute_variants] list
+ And Response body parameter should have datatype: [data][attributes][attributeMap][attribute_variant_map] dict
+ And Response body parameter should contain: [data][attributes][superAttributes] ${abstract_available_product_with_stock.superattribute}
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes][norm]
+ And Response body has correct self link internal
+
+Get_abstract_product_with_category_nodes_included
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response should contain the array of a certain size: [included] 3
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Each array element of array in response should contain property with value: [data][relationships][category-nodes][data] type category-nodes
+ And Each array element of array in response should contain property: [data][relationships][category-nodes][data] id
+ And Response body parameter should be: [data][relationships][category-nodes][data][0][id] ${abstract_available_product_with_stock.category_nodes.category_node_14.id}
+ And Response body parameter should be: [data][relationships][category-nodes][data][1][id] ${abstract_available_product_with_stock.category_nodes.category_node_12.id}
+ And Response body parameter should be: [data][relationships][category-nodes][data][2][id] ${abstract_available_product_with_stock.category_nodes.category_node_11.id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type category-nodes
+ And Response body parameter should be: [included][0][attributes][name] ${abstract_available_product_with_stock.category_nodes.category_node_14.name}
+ And Response body parameter should be: [included][1][attributes][name] ${abstract_available_product_with_stock.category_nodes.category_node_12.name}
+ And Response body parameter should be: [included][2][attributes][name] ${abstract_available_product_with_stock.category_nodes.category_node_11.name}
+ And Each array element of array in response should contain nested property: [included] attributes nodeId
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes metaTitle
+ And Each array element of array in response should contain nested property: [included] attributes metaKeywords
+ And Each array element of array in response should contain nested property: [included] attributes metaDescription
+ And Each array element of array in response should contain nested property: [included] attributes isActive
+ And Each array element of array in response should contain nested property: [included] attributes order
+ And Each array element of array in response should contain nested property: [included] attributes url
+ And Each array element of array in response should contain nested property: [included] attributes children
+ And Each array element of array in response should contain nested property: [included] attributes parents
+
+# Verifications regarding abstract-products within included are removed as abstract-products should not be in the response body -> CC-12041
+Get_abstract_product_with_concrete_products_included
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [included][0][attributes] 15
+ And Response should contain the array of a certain size: [included][0][attributes][attributes] 8
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][concrete-products][data][0][type]
+ And Response body parameter should not be EMPTY: [data][relationships][concrete-products][data][0][id]
+ And Response body parameter should not be EMPTY: [data][relationships][concrete-products]
+ And Response body parameter should be: [data][attributes][merchantReference] ${abstract_available_product_with_stock.merchant_reference}
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][concrete-products][data] type
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][concrete-products][data] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDiscontinued]
+ And Response body parameter should be: [included][0][attributes][discontinuedNote] None
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should have datatype: [included][0][attributes][reviewCount] int
+ And Response body parameter should be: [included][0][attributes][productAbstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][name] ${abstract_available_product_with_stock.concrete_available_product.name}
+ And Response body parameter should be: [included][0][attributes][description] ${abstract_available_product_with_stock.concrete_available_product.description}
+ And Response body parameter should be: [included][0][attributes][metaTitle] ${abstract_available_product_with_stock.concrete_available_product.meta_title}
+ And Response body parameter should be: [included][0][attributes][metaKeywords] ${abstract_available_product_with_stock.concrete_available_product.meta_keywords}
+ And Response body parameter should be: [included][0][attributes][metaDescription] ${abstract_available_product_with_stock.concrete_available_product.meta_description}
+ And Response body parameter should contain: [data][attributes][superAttributes] ${abstract_available_product_with_stock.superattribute}
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes]
+ And Response body parameter should not be EMPTY: [included][0][attributes][superAttributesDefinition]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributeNames]
+
+Get_abstract_product_with_product_options_included
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response should contain the array of a certain size: [included] 4
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Each array element of array in response should contain property: [data][relationships][product-options][data] type
+ And Each array element of array in response should contain property: [data][relationships][product-options][data] id
+ And Response body parameter should be: [data][relationships][product-options][data][0][id] ${abstract_available_product_with_stock.product_options.OP_1.id}
+ And Response body parameter should be: [data][relationships][product-options][data][1][id] ${abstract_available_product_with_stock.product_options.OP_2.id}
+ And Response body parameter should be: [data][relationships][product-options][data][2][id] ${abstract_available_product_with_stock.product_options.OP_3.id}
+ And Response body parameter should be: [data][relationships][product-options][data][3][id] ${abstract_available_product_with_stock.product_options.OP_insurance.id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: product-options
+ And Each array element of array in response should contain nested property: [included] attributes optionGroupName
+ And Each array element of array in response should contain nested property: [included] attributes sku
+ And Each array element of array in response should contain nested property: [included] attributes optionName
+ And Each array element of array in response should contain nested property: [included] attributes price
+ And Each array element of array in response should contain nested property: [included] attributes currencyIsoCode
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${abstract_available_product_with_stock.product_options.OP_1.id}
+ And Response body parameter should be: [included][0][attributes][optionGroupName] ${abstract_available_product_with_stock.product_options.OP_1.option_group_name}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.product_options.OP_1.sku}
+ And Response body parameter should be: [included][0][attributes][optionName] ${abstract_available_product_with_stock.product_options.OP_1.option_name}
+ And Response body parameter should be: [included][0][attributes][price] None
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][1][id] ${abstract_available_product_with_stock.product_options.OP_2.id}
+ And Response body parameter should be: [included][1][attributes][optionGroupName] ${abstract_available_product_with_stock.product_options.OP_2.option_group_name}
+ And Response body parameter should be: [included][1][attributes][sku] ${abstract_available_product_with_stock.product_options.OP_2.sku}
+ And Response body parameter should be: [included][1][attributes][optionName] ${abstract_available_product_with_stock.product_options.OP_2.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][2][id] ${abstract_available_product_with_stock.product_options.OP_3.id}
+ And Response body parameter should be: [included][2][attributes][optionGroupName] ${abstract_available_product_with_stock.product_options.OP_3.option_group_name}
+ And Response body parameter should be: [included][2][attributes][sku] ${abstract_available_product_with_stock.product_options.OP_3.sku}
+ And Response body parameter should be: [included][2][attributes][optionName] ${abstract_available_product_with_stock.product_options.OP_3.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][3][id] ${abstract_available_product_with_stock.product_options.OP_insurance.id}
+ And Response body parameter should be: [included][3][attributes][optionGroupName] ${abstract_available_product_with_stock.product_options.OP_insurance.option_group_name}
+ And Response body parameter should be: [included][3][attributes][sku] ${abstract_available_product_with_stock.product_options.OP_insurance.sku}
+ And Response body parameter should be: [included][3][attributes][optionName] ${abstract_available_product_with_stock.product_options.OP_insurance.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+
+
+Get_abstract_product_with_product_labels_included
+ [Setup] Trigger product labels update
+ When I send a GET request: /abstract-products/${abstract_product.abstract_product_with_label.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_product.abstract_product_with_label.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][product-labels]
+ And Response include should contain certain entity type: product-labels
+ And Each array element of array in response should contain property: [data][relationships][product-labels][data] type
+ And Each array element of array in response should contain property: [data][relationships][product-labels][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${label_new.id}
+ And Response body parameter should be: [included][0][type] product-labels
+ And Response body parameter should be: [included][0][attributes][name] ${label_new.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should be: [included][0][attributes][position] 2
+ And Response body parameter should be: [included][0][attributes][frontEndReference] new
+
+Get_abstract_product_with_merchants_included
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: merchants
+ And Each array element of array in response should contain property: [data][relationships][merchants][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchants][data] id
+ And Response body parameter should be: [data][relationships][merchants][data][0][type] merchants
+ And Response body parameter should be: [data][relationships][merchants][data][0][id] ${merchants.merchant_spryker_id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response body parameter should be: [included][0][id] ${merchants.merchant_spryker_id}
+ And Response body parameter should be: [included][0][type] merchants
+ And Response body parameter should be: [included][0][attributes][merchantName] ${merchants.merchant_spryker_name}
+ And Response body parameter should be: [included][0][attributes][merchantUrl] ${merchants.merchant_spryker_url}
+ And Response body parameter should be: [included][0][attributes][contactPersonRole] ${merchants.contact_spryker_person_role}
+ And Response body parameter should be: [included][0][attributes][contactPersonTitle] ${merchants.contact_spryker_person_title}
+ And Response body parameter should be: [included][0][attributes][contactPersonFirstName] ${merchants.contact_spryker_person_first_name}
+ And Response body parameter should be: [included][0][attributes][contactPersonLastName] ${merchants.contact_spryker_person_last_name}
+ And Response body parameter should be: [included][0][attributes][contactPersonPhone] ${merchants.contact_spryker_person_phone}
+ And Response body parameter should be: [included][0][attributes][publicEmail] ${merchants.spryker_public_email}
+ And Response body parameter should be: [included][0][attributes][publicPhone] ${merchants.spryker_public_phone}
+ And Response body parameter should be: [included][0][attributes][description] ${merchants.description_spryker}
+
+Abstract_product_in_different_locales_languages
+ When I set Headers: Accept-Language=de-DE
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_de}
+ When I set Headers: Accept-Language=en-US
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_en}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/negative.robot
new file mode 100644
index 0000000..9fefa67
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_acess_token_with_invalid_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":"fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_invalid_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"fake@spryker.com","password":"${yves_user.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_empty_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+
+Get_acess_token_with_empty_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: username => This value should not be blank.
+
+Get_acess_token_with_invalid_type
+ When I send a POST request: /access-tokens {"data":{"type":"access","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_acess_token_with_empty_type
+ When I send a POST request: /access-tokens {"data":{"type":"","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/positive.robot
new file mode 100644
index 0000000..0b73864
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/access_tokens/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_access_token_for_customer
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body should contain: idCompanyUser
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/negative.robot
new file mode 100644
index 0000000..747235e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/negative.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+#######POST#######
+Refresh_token_with_access_token
+ [Setup] I get access token for the customer: ${yves_user.email}
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_invalid_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "faketoken"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_empty_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": ""}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: refreshToken => This value should not be blank.
+
+Refresh_token_with_invalid_type
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "access-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Refresh_token_with_deleted_refresh_token
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ ... AND I set Headers: Authorization=Bearer ${access_token}
+ ... AND I send a DELETE request: /refresh-tokens/${refresh_token}
+ ... AND Response status code should be: 204
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Failed to refresh token.
+
+#######DELETE#######
+# Spryker is designed so removing non-existent refresh token will return 204 for security reasons
+Delete_refresh_token_with_invalid_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /refresh-tokens/faketoken
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_refresh_token_with_missing_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_refresh_token_with_no_access_token
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Spryker is designed so that deleting will return 204, but the token will not be removed and can be used (done for security reasons)
+Delete_refresh_token_for_another_user
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Authorization=Bearer ${access_token}
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/positive.robot
new file mode 100644
index 0000000..45485d1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/refresh_tokens/positive.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Refresh_access_token_for_customer
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Save value to a variable: [data][attributes][accessToken] refreshed_access_token
+ And Response body has correct self link internal
+ When I set Headers: Authorization=Bearer ${refreshed_access_token}
+ And I send a GET request: /customers
+ Then Response status code should be: 200
+
+Delete_refresh_token_for_customer
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I set Headers: Authorization=Bearer ${access_token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/negative.robot
new file mode 100644
index 0000000..af166d8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/negative.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer_with_invalid_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "invalid_grant_type","username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_missing_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_invalid_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "wrong_password"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_for_customer_with_invalid_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "fake@spryker.com","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","password": "${yves_user.password}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+
+Get_token_using_refresh_token_for_customer_with_missing_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "invalid_grant_type","refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_missing_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "invalid_refresh_token"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The refresh token is invalid.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/positive.robot
new file mode 100644
index 0000000..5926b5e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/access_token_endpoints/token/positive.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer
+ I set Headers: Content-Type=${urlencoded_header_content_type}
+ I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ Response status code should be: 200
+ Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+
+Get_token_using_refresh_token_for_customer
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "${refresh_token}"}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/negative.robot
new file mode 100644
index 0000000..8783e3b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/negative.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_token_for_user_who_is_not_agent
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_non-existent_email
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "fake@spryker.com","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_email
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_wrong_type
+ When I send a POST request: /agent-access-tokens {"data": {"type": "access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/positive.robot
new file mode 100644
index 0000000..dd015d2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_access_token/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_access_token
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
new file mode 100644
index 0000000..632dd01
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
@@ -0,0 +1,73 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_cannot_impersonate_customer_with_no_agent_token
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_wrong_token_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_invalid_token
+ [Setup] I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer fake
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Agent_cannot_impersonate_customer_with_wrong_type
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-token","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Agent_cannot_impersonate_customer_with_invalid_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_empty_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_missing_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
new file mode 100644
index 0000000..da91bc1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
@@ -0,0 +1,44 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_customer_impersonation_token
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-customer-impersonation-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
+
+Customer_impersonation_token_can_be_used
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ ... AND I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] impersonation_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${impersonation_token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"name": "cart${random}","priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] cart_uid
+ And I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ And Response status code should be: 201
+ When I get access token for the customer: ${yves_user.email}
+ And I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ Then I send a GET request: /carts/${cart_uid}?include=items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/negative.robot
new file mode 100755
index 0000000..3c01972
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/negative.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_searches_for_customers_with_no_token
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_searches_for_customers_with_customer_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/positive.robot
new file mode 100755
index 0000000..32504c6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/agent_endpoints/agent_customer_search/positive.robot
@@ -0,0 +1,156 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_search_for_customers_without_search_parameters
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 10
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${customer_reference.de_1}
+ And Response body parameter should be: [data][0][attributes][customers][9][customerReference] ${customer_reference.de_10}
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_first_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.first_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_last_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.last_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_email
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.email}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=so
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 2
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring_and_not_find_any
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=ghjk
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 0
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_with_larger_page_size
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=0&page[limit]=15
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 15
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${customer_reference.de_1}
+ And Response body parameter should be: [data][0][attributes][customers][14][customerReference] ${customer_reference.de_15}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body parameter should not be EMPTY: [links][self]
+
+Agent_can_get_search_for_customers_from_last_page
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=30&page[limit]=10
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 6
+ And Response body parameter should be: [data][0][attributes][customers][5][customerReference] ${customer_reference.de_34}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][self]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/negative.robot
new file mode 100644
index 0000000..c4a2ca6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/negative.robot
@@ -0,0 +1,119 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_without_customerId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers//availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 4606
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_with_invalid_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=325tr
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Authorization=
+ ... AND I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_without_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+Subscribe_to_availability_notifications_with_non_existent_sku
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "fake","email": "${yves_user.email}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Each array element of array in response should contain property with value: [errors] code 4601
+ And Each array element of array in response should contain property with value: [errors] status ${404}
+ And Array in response should contain property with value: [errors] detail Product not found.
+
+Subscribe_to_availability_notifications_with_invalid_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "gmail"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail email => This value is not a valid email address.
+
+Subscribe_to_availability_notifications_with_empty_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "","email": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+
+Subscribe_to_availability_notifications_without_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+
+Subscribe_to_availability_notifications_with_existing_subscription
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4602
+ And Response should return error message: Subscription already exists.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_with_invalid_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/7fc6ebf
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4603
+ And Response should return error message: "Subscription doesnt exist."
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Delete_availability_notifications_without_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/positive.robot
new file mode 100644
index 0000000..f1f657c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/availability_notifications/positive.robot
@@ -0,0 +1,79 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][0][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_discontinued.sku}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_empty_list_of_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+#POST requests
+Subscribe_to_availability_notifications_for_customer
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_discontinued.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Subscribe_to_availability_notifications_with_non_existing_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "sonia+${random}@spryker.com"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][attributes][email] sonia+${random}@spryker.com
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_discontinued.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/${availability_notification_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/negative.robot
new file mode 100644
index 0000000..cb5ac00
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Retrieves_my_availability_notifications_with_missing_auth_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_my_availability_notifications_with_invalid_auth_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/positive.robot
new file mode 100644
index 0000000..428e6bd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/availability_endpoints/my_availability_notifications/positive.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_my_availability_notifications
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_discontinued.sku}","email": "${yves_user.email}"}}}
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][0][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_discontinued.sku}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] localeName
+ And Each array element of array in response should contain nested property: [data] [attributes] email
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/negative.robot
new file mode 100644
index 0000000..caa2175
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_bundled_products_with_nonexisting_concrete_sku
+ [Documentation] there is a bug - https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/fake/bundled-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_bundled_products_with_invalid_concrete_sku
+ [Documentation] there is a bug - https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/:sku/bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_bundled_products_with_missing_concrete_sku
+ When I send a GET request: /concrete-products//bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/positive.robot
new file mode 100644
index 0000000..0d07452
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/bundle_endpoints/bundled_products/positive.robot
@@ -0,0 +1,91 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_concrete_bundled_products_inside_concrete_bundle
+ [Documentation] no demo data - https://spryker.atlassian.net/browse/MP-6888; product bundles aren`t supported on b2b-mp for now
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/${bundle_product.concrete.sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Response body parameter should be: [data][0][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be: [data][1][attributes][sku] ${bundle_product.concrete.product_2_sku}
+ And Response body parameter should be: [data][2][attributes][sku] ${bundle_product.concrete.product_3_sku}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][quantity] ${bundle_product.products_in_bundle.qty_of_each_product}
+ And Response body has correct self link
+
+Get_concrete_bundled_products_inside_concrete_bundle_with_included_concretes
+ [Documentation] no demo data - https://spryker.atlassian.net/browse/MP-6888; product bundles aren`t supported on b2b-mp for now
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/${bundle_product.concrete.sku}/bundled-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property with value: [data] [relationships][concrete-products][data][0][type] concrete-products
+ And Response should contain the array of a certain size: [included] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+
+Get_concrete_bundle_product_with_bundled_products_include
+ [Documentation] no demo data - https://spryker.atlassian.net/browse/MP-6888; product bundles aren`t supported on b2b-mp for now
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/${bundle_product.concrete.sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete.sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.sku}
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.concrete.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data][relationships][bundled-products][data] type bundled-products
+ And Response should contain the array larger than a certain size: [included] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_abstract_bundle_product_with_bundled_products_include
+ [Documentation] no demo data - https://spryker.atlassian.net/browse/MP-6888; product bundles aren`t supported on b2b-mp for now
+ [Tags] skip-due-to-issue
+ When I send a GET request: /abstract-products/${bundle_product.abstract.sku}?include=bundled-products,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.abstract.name}
+ And Response body parameter should be: [data][attributes][attributeMap][product_concrete_ids] ${bundle_product.concrete.sku}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 1
+ And Response body parameter should be: [data][relationships][concrete-products][data][0][id] ${bundle_product.concrete.sku}
+ And Response should contain the array larger than a certain size: [included] ${bundle_product.products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+ And Response include element has self link: abstract-products
+
+Get_concrete_bundled_products_for_nonbundle_product
+ When I send a GET request: /concrete-products/${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot
new file mode 100644
index 0000000..eccd0e7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/negitive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core acl shared-carts
+
+*** Test Cases ***
+Get_cart_permission_group_with_unauthenicated_user
+ When I send a GET request: /cart-permission-groups/1
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_cart_permission_group_by_non_exist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/111111
+ Then Response status code should be: 404
+ And Response should return error code: 2501
+ And Response should return error message: Cart permission group not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot
new file mode 100644
index 0000000..eb3e3a7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/cart_permssion_groups/positive.robot
@@ -0,0 +1,79 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core acl shared-carts multiple-carts
+
+*** Test Cases ***
+Get_cart_permission_groups_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] company_user_id
+ ... AND I send a POST request: /carts/${cart_id}/shared-carts {"data": {"type": "shared-carts","attributes": {"idCompanyUser": "${company_user_id}","idCartPermissionGroup": "2"}}}
+ When I send a GET request: /carts/${cart_id}?include=shared-carts,cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][shared-carts]
+ And Each array element of array in response should contain property: [data][relationships][shared-carts][data] type
+ And Each array element of array in response should contain property: [data][relationships][shared-carts][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value in: [included] type cart-permission-groups shared-carts
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 2
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDefault]
+ And Response body parameter should be in: [included][0][attributes][isDefault] true false
+ And Response body parameter should be: [included][1][type] shared-carts
+ And Response body parameter should be: [included][1][attributes][idCompanyUser] ${company_user_id}
+ And Response body parameter should be: [included][1][attributes][idCartPermissionGroup] 2
+ And Response body parameter should not be EMPTY: [included][1][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property: [included][1][relationships][cart-permission-groups][data] type
+ And Each array element of array in response should contain property: [included][1][relationships][cart-permission-groups][data] id
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_all_cart_permission_groups
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type cart-permission-groups
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDefault] True False
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Get_cart_permission_groups_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/${cart_permission_group_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter Should Be: [data][type] cart-permission-groups
+ And Response body parameter should Be: [data][id] ${cart_permission_group_id}
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][isDefault]
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/negative.robot
new file mode 100644
index 0000000..6bffce1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/negative.robot
@@ -0,0 +1,406 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core
+
+*** Test Cases ***
+#GET requests
+Get_cart_by_cart_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_cart_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/12345678
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_cart_by_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_customer_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=234567thgf
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_customer_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/user-01/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#POST requests
+Create_cart_with_invalid_access_token
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_without_access_token
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_cart_with_invalid_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "D","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 112
+ And Response should return error message: Store data is invalid.
+
+Create_cart_with_invalid_priceMod_and_currency
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ And Response body parameter should be: [errors][2][code] 107
+ And Response body parameter should be: [errors][2][detail] Failed to create cart.
+
+Create_cart_with_empty_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": "","name": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail priceMode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail currency => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail store => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+
+Create_cart_without_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail priceMode => This field is missing.
+ And Array in response should contain property with value: [errors] detail currency => This field is missing.
+ And Array in response should contain property with value: [errors] detail store => This field is missing.
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+
+
+#PATCH requests
+Update_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=ETag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Update_cart_without_access_token
+ [Setup] I set Headers: Authorization= If-Match=If-Match=ETag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+Update_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/8567km {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/ {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_from_another_customer_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match="3278654tv3"
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 428
+ And Response reason should be: Precondition Required
+ And Response should return error message: If-Match header is missing.
+ And Response should return error code: 005
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "car","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: name => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "DEK"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#DELETE requests
+Delete_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=iuhiu6gi7
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Delete_cart_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Delete_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/88ca6f79
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Delete_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/positive.robot
new file mode 100644
index 0000000..9245ab9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/carts/positive.robot
@@ -0,0 +1,436 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax promotions-discounts marketplace-promotions-discounts spryker-core customer-access multiple-carts
+
+*** Test Cases ***
+# GET requests
+Get_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_without_cart_id
+# Spryker is designed so that we can get all carts same as for /customers/{customerId}/carts request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] priceToPay
+ And Each array element of array in response should contain nested property: [data] [attributes] discounts
+ And Each array element of array in response should contain property: [data] links
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_cart_id_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_available_product.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] sku_1_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] sku_2_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_original_prices.concrete_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][2][id] sku_3_id
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][items][data] 3
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Response body parameter should be: [data][relationships][items][data][0][id] ${sku_1_id}
+ And Response body parameter should be: [data][relationships][items][data][1][id] ${sku_2_id}
+ And Response body parameter should be: [data][relationships][items][data][2][id] ${sku_3_id}
+ And Response should contain the array of a certain size: [included] 3
+ And Each array element of array in response should contain property with value: [included] type items
+ And Response body parameter should be: [included][0][id] ${sku_1_id}
+ And Response body parameter should be: [included][1][id] ${sku_2_id}
+ And Response body parameter should be: [included][2][id] ${sku_3_id}
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][2][attributes][sku] ${abstract_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 1
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] salesUnit
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_cart_id_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_1.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] sku_1_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_2.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] sku_2_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_3.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][2][id] sku_3_id
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ #totals
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_1.total_sum_for_discounts_for_products_1_and_2} + ${discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ #discounts
+ And Response should contain the array of a certain size: [data][attributes][discounts] 2
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_1.name}
+ And Response body parameter should be: [data][attributes][discounts][0][amount] ${discount_1.total_sum_for_discounts_for_products_1_and_2}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be: [data][attributes][discounts][1][displayName] ${discount_2.name}
+ And Response body parameter should be: [data][attributes][discounts][1][amount] ${discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body has correct self link internal
+ #items
+ And Response should contain the array of a certain size: [data][relationships][items][data] 3
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Response body parameter should be: [data][relationships][items][data][0][id] ${sku_1_id}
+ And Response body parameter should be: [data][relationships][items][data][1][id] ${sku_2_id}
+ And Response body parameter should be: [data][relationships][items][data][2][id] ${sku_3_id}
+ #included
+ And Response should contain the array of a certain size: [included] 3
+ And Each array element of array in response should contain property with value: [included] type items
+ #item 1
+ And Response body parameter should be: [included][0][id] ${sku_1_id}
+ And Response body parameter should be: [included][0][attributes][sku] ${discount_concrete_product.product_1.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][calculations][unitDiscountAmountAggregation] ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][0][attributes][calculations][sumDiscountAmountAggregation] ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][0][attributes][calculations][unitDiscountAmountFullAggregation] ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][0][attributes][calculations][sumDiscountAmountFullAggregation] ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts}
+ #item 2
+ And Response body parameter should be: [included][1][id] ${sku_2_id}
+ And Response body parameter should be: [included][1][attributes][sku] ${discount_concrete_product.product_2.sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][calculations][unitDiscountAmountAggregation] ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][1][attributes][calculations][sumDiscountAmountAggregation] ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][1][attributes][calculations][unitDiscountAmountFullAggregation] ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be: [included][1][attributes][calculations][sumDiscountAmountFullAggregation] ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ #item 3
+ And Response body parameter should be: [included][2][id] ${sku_3_id}
+ And Response body parameter should be: [included][2][attributes][sku] ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 1
+ And Response body parameter should be: [included][2][attributes][calculations][unitDiscountAmountAggregation] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [included][2][attributes][calculations][sumDiscountAmountAggregation] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [included][2][attributes][calculations][unitDiscountAmountFullAggregation] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [included][2][attributes][calculations][sumDiscountAmountFullAggregation] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property: [data] attributes totals
+ And Each array element of array in response should contain nested property: [data] attributes discounts
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] priceToPay
+ And Each array element of array in response should contain nested property: [data] [attributes] discounts
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#POST requests
+Create_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link for created entity: ${cart_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_cart_with_existing_name
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id_2
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id_2}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link for created entity: ${cart_id_2}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /carts/${cart_id_2}
+ ... AND Response status code should be: 204
+
+
+
+#PATCH requests
+Update_cart_by_cart_id_with_all_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][currency] ${currency.chf.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_priceMod_currency_store
+# Spryker is designed so that we can send empty attributes: priceMod, currency, store and it will not be changed to the empty values.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_name_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_existing_name
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": "My Cart"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] "My Cart"
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#DELETE requests
+Delete_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Array in response should contain property with value: [errors] detail Cart with given uuid not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/negative.robot
new file mode 100644
index 0000000..06d3cbd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/negative.robot
@@ -0,0 +1,372 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart product configurable-product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+####### POST #######
+Add_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts//items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_item_to_cart_with_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=asdasfas
+ When I send a POST request: /carts/han/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "carts","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### PATCH #######
+Update_item_in_cart_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/fake/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_cart_with_no_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts//items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_in_cart_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/${cart_uid}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_without_changing_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts/${cart_uid}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 114
+ And Response should return error message: Cart item could not be updated.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Update_item_with_invalid_parameters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts/${cart_uid}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts/fake/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_with_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts//items/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/positive.robot
new file mode 100644
index 0000000..ed3c293
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/items/positive.robot
@@ -0,0 +1,419 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart product marketplace-product-options product-options non-splittable-products configurable-product promotions-discounts marketplace-promotions-discounts inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+####POST#####
+Add_one_item_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_two_items_to_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items,concrete-products,abstract-products {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 2}}}
+ ... AND Save value to a variable: [data][relationships][items][data][0][id] sku_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][2][type] items
+ And Response body parameter should be: [included][2][id] ${sku_id}
+ And Response body parameter should be: [included][2][attributes][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][2][attributes][quantity] 2
+ And Response body parameter should be: [included][2][attributes][groupKey] ${sku_id}
+ And Response body parameter should be: [included][2][attributes][abstractSku] ${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][2][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][2][attributes][salesUnit] None
+ And Response should contain the array of a certain size: [included][2][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Get_a_cart_with_included_items_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 2}}}
+ ... AND Save value to a variable: [data][relationships][items][data][0][id] sku_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_uid}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] Cart-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response body parameter should be: [included][1][type] items
+ And Response body parameter should be: [included][1][id] ${sku_id}
+ And Response body parameter should be: [included][1][attributes][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][1][attributes][quantity] 2
+ And Response body parameter should be: [included][1][attributes][groupKey] ${sku_id}
+ And Response body parameter should be: [included][1][attributes][abstractSku] ${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][1][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][1][attributes][salesUnit] None
+ And Response should contain the array of a certain size: [included][1][attributes][selectedProductOptions] 0
+
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+
+Add_five_items_to_cart_with_included_cart_rules_and_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items?include=cart-rules,promotional-items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_promotions}","quantity": 5}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array larger than a certain size: [data][relationships][cart-rules][data] 0
+ And Response should contain the array of a certain size: [data][relationships][promotional-items][data] 1
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: items
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_random_weight_product_to_cart_with_included_sales_units_and_measurenet_units
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a GET request: /concrete-products/${concrete_product_random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ When I send a POST request: /carts/${cart_uid}/items?include=items,sales-units,product-measurement-units {"data": {"type": "items","attributes": {"sku": "${concrete_product_random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 10}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: sales-units
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include element has self link: items
+ And Response include element has self link: sales-units
+ And Response include element has self link: product-measurement-units
+ And Response body parameter should be: [included][0][type] product-measurement-units
+ And Response body parameter should be: [included][0][id] ${packaging_unit.i}
+ And Response body parameter should be: [included][1][type] sales-units
+ And Response body parameter should be: [included][1][id] ${sales_unit_id}
+ And Response body parameter should be: [included][2][attributes][salesUnit][id] ${sales_unit_id}
+ And Response body parameter should be: [included][2][attributes][salesUnit][amount] 10
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+
+Add_product_with_options_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items?include=items {"data":{"type": "items","attributes":{"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1,"productOptions": [{ "sku": "${product_options.option_1}"},{ "sku": "${product_options.option_2}"}] }}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: items
+ And Response include element has self link: items
+ And Response body parameter should contain: [included][0][id] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should contain: [included][0][attributes][groupKey] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [included][0][attributes][calculations][unitProductOptionPriceAggregation] 1
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumProductOptionPriceAggregation] 1
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 2
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] optionGroupName
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] sku
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] optionName
+ Each array element of array in response should contain property: [included][0][attributes][selectedProductOptions] price
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_with_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_1.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_1.name}
+ And Response body parameter should be: [data][attributes][discounts][0][amount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be: [data][attributes][discounts][1][displayName] ${discount_2.name}
+ And Response body parameter should be: [data][attributes][discounts][1][amount] ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_item_without_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_3.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 1
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_2.name}
+ And Response body parameter with rounding should be: [data][attributes][discounts][0][amount] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+###### PATCH #######
+Change_item_qty_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_uid}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 5}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 5
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Change_item_amount_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a GET request: /concrete-products/${concrete_product_random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product_random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 10}}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_uid}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 2,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] 20
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+##### DELETE #######
+Delete_item_form_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_uid}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_uid}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_uid}
+ ... AND Response status code should be: 204
+
+Add_a_configurable_product_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "move-from-shopping-list-${random}"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response status code should be: 200
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response reason should be: No Content
+
+Change_configuration_and_quantity_in_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "update-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 61203
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "delete-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/negative.robot
new file mode 100644
index 0000000..d37c412
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/negative.robot
@@ -0,0 +1,361 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart shared-carts customer-access spryker-core
+
+*** Test Cases ***
+Share_not_owned_shopping_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_non_existing_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_empty_permission_group_value_and_company_user_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"","idCartPermissionGroup":""}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail idCartPermissionGroup => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail idCompanyUser => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+
+Share_shopping_cart_without_company_user_attribute_and_cart_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail idCompanyUser => This field is missing.
+ And Array in response should contain property with value: [errors] detail idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_the_other_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_ottom_admin_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 2703
+ And Response reason should be: Forbidden
+ And Response should return error message: Cart can be shared only with company users from same company.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_without_access_token
+ When I send a POST request: /carts/shoppingCartId/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Share_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a POST request: /carts/shoppingCartId/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Share_shopping_cart_with_empty_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts//shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 400
+ And Response should return error code: 104
+ And Response reason should be: Bad Request
+ And Response should return error message: Cart uuid is missing.
+
+Share_shopping_cart_with_incorrect_cart_permission_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_non_existing_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"nonExistingCompanyUserId","idCartPermissionGroup":2}}}
+ Then Response status code should be: 404
+ And Response should return error code: 1404
+ And Response reason should be: Not Found
+ And Response should return error message: Company user not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_access_token
+ When I send a PATCH request: /shared-carts/sharedCardId {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_permissions_of_shared_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a PATCH request: /shared-carts/sharedCardId {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_permissions_of_shared_shopping_cart_without_shared_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /shared-carts {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_permissions_of_shared_shopping_cart_with_incorrect_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":3}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_extra_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"test123456","idCartPermissionGroup":1}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_empty_permission_group_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":""}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/${cartId}/items/${abstract_available_product_with_stock.concrete_available_product.sku} {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_an_item_from_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}/items/${abstract_available_product_with_stock.concrete_available_product.sku}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: 403
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_already_deleted_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: 404
+ And Response should return error code: 2705
+ And Response reason should be: Not Found
+ And Response should return error message: Shared cart not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/positive.robot
new file mode 100644
index 0000000..fd40d57
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/cart_endpoints/shared_carts/positive.robot
@@ -0,0 +1,205 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shared-carts product-relations customer-access spryker-core
+
+*** Test Cases ***
+Create_a_shared_shopping_cart_with_read_only_permissions_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ And I send a GET request: /carts/${cartId}?include=shared-carts
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][type] shared-carts
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][id] ${sharedCartId}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] shared-carts
+ And Response body parameter should be: [included][0][id] ${sharedCartId}
+ And Response body parameter should be: [included][0][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [included][0][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ And I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ And Response status code should be: 200
+ And Response body parameter should be: [data][relationships][cart-permission-groups][data][0][type] cart-permission-groups
+ And Response body parameter should be: [data][relationships][cart-permission-groups][data][0][id] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 1
+ And Response body parameter should be: [included][0][attributes][isDefault] True
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shared_shopping_cart_with_full_access_permissions
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 2
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] FULL_ACCESS
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_by_Cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a PATCH request: /shared-carts/${sharedCartId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property: [data][relationships][cart-permission-groups][data] type
+ And Each array element of array in response should contain property: [data][relationships][cart-permission-groups][data] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [included][0][id] sku_id
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${sku_id}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [included][0][id] itemId
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] itemTotalPrice
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/${cartId}/items/${itemId}?include=items {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${itemId}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${itemTotalPrice}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_an_item_from_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts/${cartId}?include=items
+ ... AND Save value to a variable: [data][relationships][items][data][0][id] itemId
+ When I send a DELETE request: /carts/${cartId}/items/${itemId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cartId}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":2}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_by_cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a DELETE request: /shared-carts/${sharedCartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/negative.robot
new file mode 100644
index 0000000..4793bdd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_by_invalid_id
+ When I send a GET request: /category-nodes/test
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
+
+Get_category_node_by_non_exist_id
+ When I send a GET request: /category-nodes/111111
+ Then Response status code should be: 404
+ And Response should return error code: 703
+ And Response should return error message: "Cant find category node with the given id."
+
+Get_absent_category_node
+ When I send a GET request: /category-nodes
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/positive.robot
new file mode 100644
index 0000000..3e54f73
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_nodes/positive.robot
@@ -0,0 +1,58 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_is_root_by_id
+ When I send a GET request: /category-nodes/${category_node_is_root_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_is_root_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][parents] 0
+ And Response should contain the array larger than a certain size: [data][attributes][children] 1
+ And Response body has correct self link internal
+
+Get_category_node_has_children_by_id
+ When I send a GET request: /category-nodes/${category_node_has_children_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_has_children_id}
+ And Response body parameter should be: [data][attributes][nodeId] ${category_node_has_children_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] nodeId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] name
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] order
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] children
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] parents
+ And Response body has correct self link internal
+
+
+Get_category_node_that_has_only_parents_by_id
+ When I send a GET request: /category-nodes/${category_node_has_only_parent_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_has_only_parent_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][children] 0
+ And Response should contain the array larger than a certain size: [data][attributes][parents] 0
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_trees/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_trees/positive.robot
new file mode 100644
index 0000000..5cabcc6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/category_endpoints/category_trees/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_trees
+ When I send a GET request: /category-trees
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type category-trees
+ And Each array element of array in response should contain property with value: [data] id ${NONE}
+ And Response body parameter should be: [data][0][type] category-trees
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] nodeId
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] order
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] url
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] children
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][name] ${category_nodes_storage_name}
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][url] ${category_nodes_storage_url}
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][1][children][0][nodeId]
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][1][children][0][order]
+ And Response body parameter should be in: [data][0][attributes][categoryNodesStorage][1][children][1][name] ${subcategory_nodes_storage_name} ${subcategory_nodes_storage_name1}
+ And Response body parameter should be in: [data][0][attributes][categoryNodesStorage][1][children][1][url] ${subcategory_nodes_storage_url} ${subcategory_nodes_storage_url1}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][1][children][0][children] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage] ${qty_of_categories_in_category_trees}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][1][children] ${qty_of_subcategories_in_category_trees}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/negative.robot
new file mode 100644
index 0000000..7f7746a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/negative.robot
@@ -0,0 +1,437 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product spryker-core
+
+*** Test Cases ***
+#POST requests
+Create_order_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "fake_email","salutation": "Freulein","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Create_order_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Create_order_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Billing address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a GET request: /carts/${cartId}/?include=items
+ ... AND Save value to a variable: [included][0][id] item_group_key
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shipments": [{"requestedDeliveryDate": "2021-09-29", "idShipmentMethod": 1, "items": ["${itemGroupKey}"], "shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false}}],"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_payment.method_name","paymentSelection": "fake_payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Checkout payment is not valid
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "","paymentMethodName": "","paymentSelection": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Shipment method not found.
+ And Response should return error code: 1102
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": []}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1104
+ And Response should return error message: Cart is empty.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_lower_order_total_price_than_threshold_limit
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_threshold_limit}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Response status code should be: 201
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_threshold_limit}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: "You should add items for €40.00 to pass a recommended threshold. You cant proceed with checkout"
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_regular_shipment_&_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"shipments": [{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4301
+ And Response should return error message: Single and multiple shipments attributes are not allowed in the same request.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_invalid_delivery_date
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "None"},{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": "None"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shipments.0.requestedDeliveryDate => This value is not a valid date.
+ And Array in response should contain property with value: [errors] detail shipments.1.requestedDeliveryDate => This value is not a valid date.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_invalid_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a GET request: /carts/${cartId}/?include=items
+ ... AND Save value to a variable: [included][0][id] first_item_group_key
+ ... AND Save value to a variable: [included][1][id] second_item_group_key
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${firstItemGroupKey}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${secondItemGroupKey}"],"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_empty_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4302
+ And Response should return error message: Provided address is not valid. You can either provide address ID or address fields.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_order_with_split_shipments_&_without_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"],"shippingAddress": {},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: shipments.1.shippingAddress => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/positive.robot
new file mode 100644
index 0000000..7a29add
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout/positive.robot
@@ -0,0 +1,595 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product payments inventory-management marketplace-inventory-management default-run-feature
+
+*** Test Cases ***
+ #POST requests
+Create_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 70, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_include_orders
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][attributes][merchantReferences] ${merchants.merchant_spryker_id}
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][merchantReference] ${merchants.merchant_spryker_id}
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesUnit] None
+ Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [included][0][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_net_mode_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 15, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 5},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_with_weight_product_&_product_options
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a GET request: /concrete-products/${concrete_product_random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}","productOptions": [{"sku": "${product_options.option_1}"}]}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_random_weight.sku}","quantity": 1,"merchantReference" : "${merchants.merchant_spryker_id}","salesUnit": {"id": "${sales_unit_id}","amount": 10}}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}", "${abstract_product.product_with_options.concrete_sku}", "${concrete_product_random_weight.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ #product_1
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ #product_2
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][optionGroupName] Three (3) year limited warranty
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][sku] ${product_options.option_1}
+ And Response body parameter should be: [included][0][attributes][items][1][productOptions][0][optionName] ${product_options.option_1_name}
+ And Response body parameter should be greater than: [included][0][attributes][items][1][productOptions][0][price] 0
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ #product_3
+ And Response body parameter should be: [included][0][attributes][items][2][name] ${concrete_product_random_weight.name}
+ And Response body parameter should be: [included][0][attributes][items][2][sku] ${concrete_product_random_weight.sku}
+ And Response should contain the array of a certain size: [included][0][attributes][items][2][productOptions] 0
+ And Response body parameter should be: [included][0][attributes][items][2][quantity] 1
+ And Response body parameter should be: [included][0][attributes][items][2][salesUnit][productMeasurementUnit][name] Item
+ And Response body parameter should be: [included][0][attributes][items][2][salesUnit][productMeasurementUnit][code] ${packaging_unit.i}
+ And Response body has correct self link internal
+
+Create_order_with_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] sku_1_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][1][id] sku_2_id
+ ... AND Response body parameter should be: [data][type] carts
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${sku_1_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${sku_2_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [included][0][attributes][shipments] 0
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 2
+
+Create_order_with_split_shipments_&_same_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] sku_1_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][1][id] sku_2_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${sku_1_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${sku_2_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+
+Create_order_with_same_items_in_different_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 2, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] sku_1_id
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${sku_1_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${sku_1_id}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 1
+
+Create_order_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 3, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [included][0][attributes][totals][expenseTotal] ${discount_3.total_sum}
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 30000
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount_3.total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [included][0][attributes][items] 3
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultGrossPrice] ${discount_3.total_sum}
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_3.total_sum}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_3.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_3.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+Create_order_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_1.sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_2.sku}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_3.sku}","quantity": 1, "merchantReference" : "${merchants.merchant_office_king_id}"}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${discount_concrete_product.product_1.sku}", "${discount_concrete_product.product_2.sku}", "${discount_concrete_product.product_3.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body has correct self link internal
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts} + ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ #item 1 - "20% off storage" discount and "10% off minimum order" discount
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][calculatedDiscounts] 2
+ And Response body parameter should be in: [included][0][attributes][items][0][merchantReference] ${merchants.merchant_spryker_id} ${merchants.merchant_office_king_id}
+ And Response body parameter should be in: [included][0][attributes][items][0][name] ${discount_concrete_product.product_1.name} ${discount_concrete_product.product_2.name} ${discount_concrete_product.product_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][sku] ${discount_concrete_product.product_1.sku} ${discount_concrete_product.product_2.sku} ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ #item 1 - ""10% off minimum order" discount
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][1][quantity] 1
+ # item 2 - "20% off storage" discount
+ And Response should contain the array of a certain size: [included][0][attributes][items][1][calculatedDiscounts] 2
+ And Response body parameter should be in: [included][0][attributes][items][1][merchantReference] ${merchants.merchant_spryker_id} ${merchants.merchant_office_king_id}
+ And Response body parameter should be in: [included][0][attributes][items][1][name] ${discount_concrete_product.product_1.name} ${discount_concrete_product.product_2.name} ${discount_concrete_product.product_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][sku] ${discount_concrete_product.product_1.sku} ${discount_concrete_product.product_2.sku} ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][quantity] 1
+ #item 2 - "10% off minimum order" discount
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order} ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order} ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][displayName] ${discount_2.name} ${discount_1.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][description] ${discount_2.description} ${discount_1.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][quantity] 1
+ #item 3 - "10% off minimum order" discount
+ And Response should contain the array of a certain size: [included][0][attributes][items][2][calculatedDiscounts] 1
+ And Response body parameter should be in: [included][0][attributes][items][2][merchantReference] ${merchants.merchant_spryker_id} ${merchants.merchant_office_king_id}
+ And Response body parameter should be in: [included][0][attributes][items][2][name] ${discount_concrete_product.product_1.name} ${discount_concrete_product.product_2.name} ${discount_concrete_product.product_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][2][sku] ${discount_concrete_product.product_1.sku} ${discount_concrete_product.product_2.sku} ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be: [included][0][attributes][items][2][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [included][0][attributes][items][2][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [included][0][attributes][items][2][calculatedDiscounts][0][displayName] ${discount_2.name} ${discount_1.name}
+ And Response body parameter should be in: [included][0][attributes][items][2][calculatedDiscounts][0][description] ${discount_2.description} ${discount_1.description}
+ And Response body parameter should be: [included][0][attributes][items][2][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][2][calculatedDiscounts][0][quantity] 1
+ #calculatedDiscounts - "20% off storage" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_1.total_sum_for_discounts_for_products_1_and_2}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_1.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_1.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 3
+ #calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_2.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_2.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 3
+
+
+
+Create_order_with_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"merchantReference" : "${merchants.merchant_spryker_id}","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_product.sku}"]}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_product.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_product.sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesOrderItemConfiguration][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/negative.robot
new file mode 100644
index 0000000..1de3c1f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/negative.robot
@@ -0,0 +1,296 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment marketplace-shipment spryker-core
+
+*** Test Cases ***
+#POST requests
+Provide_checkout_data_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+Provide_checkout_data_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "fake_email","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Provide_checkout_data_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Provide_checkout_data_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/positive.robot
new file mode 100644
index 0000000..2ab1a50
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/checkout_endpoints/checkout_data/positive.robot
@@ -0,0 +1,196 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment marketplace-shipment spryker-core
+
+*** Test Cases ***
+#POST requests
+Provide_checkout_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_with_only_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data", "attributes": {"idCart": "${cart_id}","payments": []}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_method_name"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete.product_2_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/negative.robot
new file mode 100644
index 0000000..b41976c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/negative.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/123456
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
+
+Request_company_without_access_token
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_company_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/positive.robot
new file mode 100644
index 0000000..c1c2eb2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/companies/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_by_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] companies
+ And Response body parameter should be: [data][id] ${company_id}
+ And Response body parameter should be: [data][attributes][name] ${company_name}
+ And Response body parameter should be: [data][attributes][status] approved
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][attributes] 3
+
+Request_company_by_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] companies
+ And Response body parameter should be: [data][0][attributes][name] ${company_name}
+ And Response body parameter should be: [data][0][attributes][status] approved
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][0][attributes] 3
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/negative.robot
new file mode 100644
index 0000000..015cfd6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/negative.robot
@@ -0,0 +1,53 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_unit_with_empty_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /company-business-units/456789
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_business_unit_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=InvalidAccessToken
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Request_business_unit_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/wrongId
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1901
+ And Response should return error message: Company business unit not found.
+
+Request_business_unit_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1901
+ And Response should return error message: Company business unit not found.
+
+Request_business_unit_with_customer_has_no_company_assignement
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 1903
+ And Response should return error message: Current company user is not set. You need to select the current company user with /company-user-access-tokens in order to access the resource collection.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/positive.robot
new file mode 100644
index 0000000..9879dcb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit/positive.robot
@@ -0,0 +1,132 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_unit_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response should contain the array of a certain size: [data][attributes] 7
+ And Response body parameter should be: [data][attributes][defaultBillingAddress] None
+ And Response body parameter should be: [data][attributes][name] ${business_unit.name}
+ And Response body parameter should not be EMPTY: [data][attributes][email]
+ And Response body parameter should not be EMPTY: [data][attributes][phone]
+ And Response body parameter should contain: [data][attributes] externalUrl
+ And Response body parameter should contain: [data][attributes] bic
+ And Response body parameter should contain: [data][attributes] iban
+ And Response body has correct self link internal
+
+Request_business_unit_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response should contain the array of a certain size: [data][0][attributes] 7
+ And Response body parameter should be: [data][0][attributes][defaultBillingAddress] None
+ And Response body parameter should be: [data][0][attributes][name] ${business_unit.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][phone]
+ And Response body parameter should contain: [data][0][attributes] externalUrl
+ And Response body parameter should contain: [data][0][attributes] bic
+ And Response body parameter should contain: [data][0][attributes] iban
+ And Response body has correct self link
+
+Request_business_unit_by_id_with_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request: /company-business-units/${business_unit_id}?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should be: [data][id] ${business_unit_id}
+ And Response should contain the array of a certain size: [data][attributes] 7
+ And Response body parameter should be: [data][attributes][defaultBillingAddress] None
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][email]
+ And Response body parameter should not be EMPTY: [data][attributes][phone]
+ And Response body parameter should contain: [data][attributes] externalUrl
+ And Response body parameter should contain: [data][attributes] bic
+ And Response body parameter should contain: [data][attributes] iban
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should contain: [data][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][relationships][companies][data][0][id]
+ And Response should contain the array of a certain size: [data][relationships][company-business-unit-addresses] 1
+ And Response body parameter should contain: [data][relationships] company-business-unit-addresses
+ And Response body parameter should contain: [data][relationships][company-business-unit-addresses][data][0][type] company-business-unit-addresses
+ And Response body parameter should not be EMPTY: [data][relationships][company-business-unit-addresses][data][0][id]
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: companies
+ And Response include should contain certain entity type: company-business-unit-addresses
+ And Response body parameter should not be EMPTY: [included][0][id]
+ And Response body parameter should not be EMPTY: [included][1][id]
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should not be EMPTY: [included][0][attributes][isActive]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][status]
+ And Response body parameter should not be EMPTY: [included][1][attributes][address1]
+ And Response body parameter should not be EMPTY: [included][1][attributes][address2]
+ And Response body parameter should contain: [included][1][attributes] address3
+ And Response body parameter should not be EMPTY: [included][1][attributes][zipCode]
+ And Response body parameter should not be EMPTY: [included][1][attributes][city]
+ And Response body parameter should not be EMPTY: [included][1][attributes][phone]
+ And Response body parameter should not be EMPTY: [included][1][attributes][iso2Code]
+ And Response body parameter should contain: [included][1][attributes] comment
+ And Response body has correct self link internal
+
+Request_business_unit_by_mine_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response should contain the array of a certain size: [data][0][attributes] 7
+ And Response body parameter should be: [data][0][attributes][defaultBillingAddress] None
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][phone]
+ And Response body parameter should contain: [data][0][attributes] externalUrl
+ And Response body parameter should contain: [data][0][attributes] bic
+ And Response body parameter should contain: [data][0][attributes] iban
+ And Response should contain the array of a certain size: [data][0][relationships] 2
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should contain: [data][0][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][0][relationships][companies][data][0][id]
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: companies
+ And Response include should contain certain entity type: company-business-unit-addresses
+ And Response body parameter should not be EMPTY: [included][0][id]
+ And Response body parameter should not be EMPTY: [included][1][id]
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should not be EMPTY: [included][0][attributes][isActive]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][status]
+ And Response body parameter should not be EMPTY: [included][1][attributes][address1]
+ And Response body parameter should not be EMPTY: [included][1][attributes][address2]
+ And Response body parameter should contain: [included][1][attributes] address3
+ And Response body parameter should not be EMPTY: [included][1][attributes][zipCode]
+ And Response body parameter should not be EMPTY: [included][1][attributes][city]
+ And Response body parameter should not be EMPTY: [included][1][attributes][phone]
+ And Response body parameter should not be EMPTY: [included][1][attributes][iso2Code]
+ And Response body parameter should contain: [included][1][attributes] comment
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot
new file mode 100644
index 0000000..78d5e5c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/negative.robot
@@ -0,0 +1,39 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Get_business_unit_address_with_empty_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /company-business-unit-addresses/${business_unit.address_id}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_business_unit_address_with_invalid_access_token
+ [Setup] I set Headers: Authorization=InvalidAccessToken
+ When I send a GET request: /company-business-unit-addresses/${business_unit.address_id}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+Get_business_unit_address_with_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/WrongId
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2001
+ And Response should return error message: Company business unit address not found.
+
+Get_business_unit_address_with_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/mine
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2001
+ And Response should return error message: Company business unit address not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot
new file mode 100644
index 0000000..96de549
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_business_unit_addresses/positive.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Get_business_units_address_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/${business_unit.address_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-unit-addresses
+ And Response body parameter should be: [data][id] ${business_unit.address_id}
+ And Response should contain the array of a certain size: [data][attributes] 8
+ And Response body parameter should not be EMPTY: [data][attributes][address1]
+ And Response body parameter should not be EMPTY: [data][attributes][address2]
+ And Response body parameter should contain: [data][attributes] address3
+ And Response body parameter should not be EMPTY: [data][attributes][zipCode]
+ And Response body parameter should not be EMPTY: [data][attributes][city]
+ And Response body parameter should not be EMPTY: [data][attributes][iso2Code]
+ And Response body parameter should not be EMPTY: [data][attributes][comment]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/negative.robot
new file mode 100644
index 0000000..1f448c4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/negative.robot
@@ -0,0 +1,52 @@
+*** Settings ***
+Test Setup API_test_setup
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_role_by_wrong_company_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/wrongid12
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2101
+ And Response should return error message: Company role not found.
+
+Request_company_role_without_access_token
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_company_role_with_invalid_access_token
+ [Setup] I set Headers: Authorization=wrongtoken
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Request_company_role_if_role_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2101
+ And Response should return error message: Company role not found.
+
+Request_company_role_when_customer_has_no_company_assignment
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 2103
+ And Response should return error message: Current company user is not set. You need to select the current company user with /company-user-access-tokens in order to access the resource collection.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/positive.robot
new file mode 100644
index 0000000..123b9df
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_roles/positive.robot
@@ -0,0 +1,87 @@
+*** Settings ***
+Test Setup API_test_setup
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_role_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-roles
+ And Response body parameter should be: [data][id] ${company_role_id}
+ And Response body parameter should be in: [data][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
+
+Request_company_role_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be in: [data][0][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][1][attributes][name] Admin Buyer
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be in: [data][1][attributes][isDefault] False True
+ And Response body has correct self link
+
+Request_company_role_by_mine_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be in: [data][0][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][1][attributes][name] Admin Buyer
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be in: [data][1][attributes][isDefault] False True
+ And Response should contain the array of a certain size: [data][0][relationships] 1
+ And Response body parameter should be: [data][0][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][0][relationships][companies][data][0][id]
+ And Response include should contain certain entity type: companies
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain nested property: [included] attributes isActive
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes status
+ And Response body has correct self link
+
+Request_company_role_by_id_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-roles
+ And Response body parameter should be: [data][id] ${company_role_id}
+ And Response body parameter should be in: [data][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][relationships][companies][data][0][id]
+ And Response include should contain certain entity type: companies
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain nested property: [included] attributes isActive
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes status
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/negative.robot
new file mode 100644
index 0000000..e2c6cb1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/negative.robot
@@ -0,0 +1,68 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Request_access_token_by_invalid_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This is not a valid UUID.
+
+Request_access_token_by_empty_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This value should not be blank.
+
+Request_access_token_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_using_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=546789
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Request_access_token_with_missing_token
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_access_token_if_user_belong_to_other_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 003
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Failed to authenticate user.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/positive.robot
new file mode 100644
index 0000000..8072427
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_user_access_tokens/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Get_access_token_for_company_user_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-user-access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/negative.robot
new file mode 100644
index 0000000..5a85caf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/negative.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Retrieve_list_of_company_users_without_access_token
+ When I send a GET request: /company-users
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Retrieve_list_of_company_users_by_user_without_admin_role
+ When I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Retrieve_company_user_by_incorrect_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/qwerty
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1404
+ And Response should return error message: Company user not found
+
+Retrieve_company_user_with incorrect_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=qwerty
+ And I send a GET request: /company-users/qwerty
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Retrieve_user_who_doesn't_belong_to_company
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 1403
+ And Response should return error message: Current company user is not set. You need to select the current company user with \/company-user-access-tokens in order to access the resource collection.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/positive.robot
new file mode 100644
index 0000000..d0de2b1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/company_endpoints/company_users/positive.robot
@@ -0,0 +1,151 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core company-account customer-account-management customer-access
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Retrieve_list_of_company_users
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 12
+ And Response should contain the array of a certain size: [data][0] 4
+ And Each array element of array in response should contain value: [data] type
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Response should contain the array of a certain size: [data][0][attributes] 2
+ And Each array element of array in response should contain property with value in: [data] attributes.isActive True False
+ And Each array element of array in response should contain property with value in: [data] attributes.isDefault True False
+ And Response body has correct self link
+
+Retrieve_company_user_by_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/${company_user_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 4
+ And Response body parameter should contain: [data][type] company-users
+ And Response body parameter should contain: [data][id] ${company_user_id}
+ And Response should contain the array of a certain size: [data][attributes] 2
+ And Response body parameter should be in: [data][attributes][isActive] True False
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
+
+Retrieve_company_user_including_customers
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=customers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Response should contain the array of a certain size: [data][0][relationships][customers][data] 1
+ And Response should contain the array larger than a certain size: [included] 11
+ And Response include should contain certain entity type: customers
+ And Response include element has self link: customers
+
+Retrieve_company_user_including_company_business_units
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=company-business-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Each array element of array in response should contain property with value: [data][0][relationships][company-business-units][data] type company-business-units
+ And Response should contain the array of a certain size: [data][0][relationships][company-business-units][data] 1
+ And Response should contain the array larger than a certain size: [included] 6
+ And Response include should contain certain entity type: company-business-units
+ And Response include element has self link: company-business-units
+
+Retrieve_company_user_including_company_roles
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=company-roles
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Array element should contain nested array at least once: [data] [relationships]
+ And Response should contain the array of a certain size: [included] 6
+ And Response include should contain certain entity type: company-roles
+ And Response include element has self link: company-roles
+
+Retrieve_company_user_including_companies
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Response should contain the array of a certain size: [data][0][relationships][companies][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: companies
+ And Response include element has self link: companies
+
+Retrieve_company_users_by_mine
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] company-users
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][isDefault] False
+ And Response body has correct self link
+
+Retrieve_list_of_company_users_with_include_customers_and_filtered_by_company_role
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company-role-uuid
+ When I send a GET request: /company-users?include=customers&filter[company-roles.id]=${company-role-uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array of a certain size: [data][0][relationships] 1
+ And Response body parameter should contain: [data][0][relationships] customers
+
+Retrieve_list_of_company_users_if_user_has_4_companies
+ When I get access token for the customer: ${user_with_multiple_companies}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I add 'admin' role to company user and get company_user_uuid: ${user_with_multiple_companies} BoB-Hotel-Jim business-unit-jim-1
+ And I get access token for the company user by uuid: ${company_user_uuid}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 4
+ And Each array element of array in response should contain property with value: [data] type company-users
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
new file mode 100644
index 0000000..263b99c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_abstract_product_alternative_for_concrete_product_with_invalid_sku_of_product
+ When I send a GET request: /concrete-products/65789/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+
+Get_abstract_product_alternative_for_concrete_product_using_abstract_product_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_1_sku}/concrete-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
new file mode 100644
index 0000000..fb68345
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
@@ -0,0 +1,58 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product discontinued-products alternative-products
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_concrete_alternative_product_for_a_product_that_has_none
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_concrete_alternative_product
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Each array element of array in response should contain nested property with value: [data] type concrete-products
+ And Each array element of array in response should contain property: [data] id
+ And Response body parameter should contain: [data][0][attributes] sku
+ And Response body parameter should contain: [data][0][attributes] isDiscontinued
+ And Response body parameter should contain: [data][0][attributes] discontinuedNote
+ And Response body parameter should contain: [data][0][attributes] averageRating
+ And Response body parameter should contain: [data][0][attributes] reviewCount
+ And Response body parameter should contain: [data][0][attributes] productAbstractSku
+ And Response body parameter should contain: [data][0][attributes] name
+ And Response body parameter should contain: [data][0][attributes] description
+ And Response body parameter should contain: [data][0][attributes] attributes
+ And Response body parameter should contain: [data][0][attributes] superAttributesDefinition
+ And Response body parameter should contain: [data][0][attributes] metaTitle
+ And Response body parameter should contain: [data][0][attributes] metaKeywords
+ And Response body parameter should contain: [data][0][attributes] metaDescription
+ And Response body parameter should contain: [data][0][attributes] attributeNames
+ And Response should contain the array of a certain size: [data][0][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][0][attributes][attributeNames] 7
+ And Response body has correct self link
+
+Get_concrete_alternative_product_with_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}/concrete-alternative-products?include=concrete-product-image-sets,concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+ And Response include element has self link: concrete-product-prices
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
new file mode 100644
index 0000000..7b7d14c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_concrete_product_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Get_concrete_product_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Get_concrete_product_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_concrete_product_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
new file mode 100644
index 0000000..e5122ce
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_concrete_product_availability_by_concrete_SKU_with_stock
+ When I send a GET request: /concrete-products/${concrete_available_product_with_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_available_product_with_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body has correct self link
+
+Get_concrete_product_availability_by_concrete_SKU_with_stock_and_never_out_of_stock
+ When I send a GET request: /concrete-products/${abstract_product.product_availability.product_2.concrete_available_with_stock_and_never_out_of_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_availability.product_2.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_without_stock
+ When I send a GET request: /concrete-products/${concrete_available_product_without_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_available_product_without_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
new file mode 100644
index 0000000..f5ca0b2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_product_image_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_1_sku}/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
+
+Get_product_image_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_product_image_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_product_image_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
new file mode 100644
index 0000000..736191b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
@@ -0,0 +1,33 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_concrete_product_with_one_image_set
+ When I send a GET request: /concrete-products/${concrete_product.image_set.one.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_product.image_set.one.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
+
+Get_concrete_product_with_5_image_sets
+ When I send a GET request: /concrete-products/${concrete_product.image_set.multiple.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_product.image_set.multiple.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 5
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
new file mode 100644
index 0000000..6b4cdaa
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/negative.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_product_prices_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_1_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Get_product_prices_with_empty_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products//concrete-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_product_prices_with_special_characters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_product_prices_by_concrete_sku_product_doesn't_exist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/4567890/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Get_product_prices_without_access_token
+ When I send a GET request: /concrete-products/${concrete_product.image_set.one.sku}/concrete-product-prices
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_product_prices_without_wrong_access_token
+ [Setup] I set Headers: Authorization=8ur30jfpwoe
+ When I send a GET request: /concrete-products/${concrete_product.image_set.one.sku}/concrete-product-prices
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
new file mode 100644
index 0000000..109da66
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_product_prices/positive.robot
@@ -0,0 +1,59 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####GET####
+Get_concrete_product_with_only_default_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.image_set.one.sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.image_set.one.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body has correct self link
+
+Get_concrete_product_with_default_and_original_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${abstract_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_original_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices][0][grossAmount]
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ ${list} = Create List
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${list}
+ And Response body has correct self link
+
+Get_concrete_product_with_volume_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${abstract_product.product_with_volume_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_volume_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body has correct self link
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/negative.robot
new file mode 100644
index 0000000..0b6ea45
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/negative.robot
@@ -0,0 +1,35 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Request_product_concrete_with_product_doesn't_exist
+ When I send a GET request: /concrete-products/354656u7i8
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_1_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+
+Request_product_concrete_with_empty_SKU
+ When I send a GET request: /concrete-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_concrete_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/positive.robot
new file mode 100644
index 0000000..1542f97
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/concrete_products_endpoints/concrete_products/positive.robot
@@ -0,0 +1,94 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####GET####
+Get_concrete_product_information_by_sku
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+
+Get_concrete_product_with_included_image_sets
+ When I send a GET request: /concrete-products/${concrete_product.image_set.one.sku}?include=concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.image_set.one.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.image_set.one.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 5
+ And Response should contain the array of a certain size: [data][attributes][attributes] 5
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+
+Get_concrete_product_with_included_availabilities_and_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${abstract_product.product_with_original_prices.concrete_sku}?include=concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_original_prices.concrete_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 5
+ And Response should contain the array of a certain size: [data][attributes][attributes] 5
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-availabilities
+
+Get_concrete_product_with_included_abstract_product
+ When I send a GET request: /concrete-products/${concrete_product.image_set.multiple.sku}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.image_set.multiple.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.image_set.multiple.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+
+Get_concrete_product_with_included_product_labels
+ [Setup] Trigger product labels update
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/negative.robot
new file mode 100644
index 0000000..618cdcc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_page_list_by_fake_id
+ When I send a GET request: /cms-pages/:cms
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
+Get_cms_page_list_by_wrond_id
+ When I send a GET request: /cms-pages/${abstract_list.product_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/positive.robot
new file mode 100644
index 0000000..d480a81
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/cms_pages/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/cms_steps.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_pages_list
+ When I send a GET request: /cms-pages
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_pages.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body array element should contain property with value at least once: [data] [attributes][name] ${cms_pages.first_cms_page.name}
+ And Response body array element should contain property with value at least once: [data] [attributes][url] ${cms_pages.first_cms_page.url_en}
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value: [data] [attributes][isSearchable] True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body has correct self link
+
+Get_specific_cms_page
+ [Setup] Run Keywords I send a GET request: /cms-pages
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] cms_page_id
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][isSearchable]
+ And Response body should contain: pageKey
+ And Response body should contain: validTo
+ And Response body has correct self link internal
+
+Get_specific_cms_with_includes
+ [Setup] Add content product abstract list to cms page in DB ${cms_pages.cms_page_with_product_lists.id}
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_pages.cms_page_with_product_lists.id}?include=content-product-abstract-lists
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_pages.cms_page_with_product_lists.id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should be: [data][attributes][name] ${cms_pages.cms_page_with_product_lists.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][content-product-abstract-lists][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: content-product-abstract-lists
+ And Response include element has self link: content-product-abstract-lists
+ [Teardown] Run Keyword Delete latest cms page version by uuid from DB ${cms_pages.cms_page_with_product_lists.id}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/negative.robot
new file mode 100644
index 0000000..69f4cbf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner_without_id
+ When I send a GET request: /content-banners
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_banner_with_wrong_content_id_type
+ When I send a GET request: /content-banners/${abstract_list.product_id}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 2203
+ And Response should return error message: Content type is invalid.
+
+Get_banner_with_invalid_content_id
+ When I send a GET request: /content-banners/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/positive.robot
new file mode 100644
index 0000000..3c60825
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_banners/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner
+ When I send a GET request: /content-banners/${banner_1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${banner_1.id}
+ And Response body parameter should be: [data][type] content-banners
+ And Response body parameter should be: [data][attributes][title] ${banner_1.name}
+ And Response body parameter should not be EMPTY: [data][attributes][subtitle]
+ And Response body parameter should contain: [data][attributes][imageUrl] jpg
+ And Response body parameter should not be EMPTY: [data][attributes][clickUrl]
+ And Response body parameter should be: [data][attributes][altText] ${banner_1.name}
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot
new file mode 100644
index 0000000..22fa663
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Get_abstract_product_list_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_products_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_with_no_id
+ When I send a GET request: /content-product-abstract-lists
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_missing_id
+ When I send a GET request: /content-product-abstract-lists//abstract-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_no_id
+ When I send a GET request: /content-product-abstract-lists/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot
new file mode 100644
index 0000000..cf84b28
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/content_endpoints/content_product_abstract_lists/positive.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Abstract_product_list
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+
+Abstract_product_list_abstract_products
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}/abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_list.size}
+ And Each array element of array in response should contain property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_list.product1_sku}
+ And Response body parameter should be: [data][0][attributes][name] ${abstract_list.product1_name}
+ And Response body parameter should be: [data][1][attributes][sku] ${abstract_list.product2_sku}
+ And Response body parameter should be: [data][1][attributes][name] ${abstract_list.product2_name}
+
+# there is a bug in b2b and mp_b2b - include does not work
+# fails in mp_b2b CC-16994
+Abstract_product_list_with_include
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-products][data] ${abstract_list.size}
+ And Response should contain the array of a certain size: [included] ${abstract_list.size}
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/negative.robot
new file mode 100644
index 0000000..87c9cef
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/negative.robot
@@ -0,0 +1,307 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+######POST#####
+Create_customer_address_with_missing_required_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address3": "${default.address3}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail city => This field is missing.
+ And Array in response should contain property with value: [errors] detail iso2Code => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultShipping => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultBilling => This field is missing.
+
+Create_customer_address_with_empty_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","country": "","iso2Code": "","company":"","phone": "","isDefaultShipping": "","isDefaultBilling": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+
+Create_customer_address_with_invalid_salutation
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "Fake","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+
+Create_customer_address_with_customer_reference_not_matching_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_non_existing_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/DE--10000/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers//addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_type
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+######GET#####
+Get_non-existent_customer_address
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Get_other_customer_address_list
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_address_list_for_non-existent_customer
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/fake/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Get_address_list_with_no_token
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Get_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_other_customer_address_by_id_and_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+######PATCH#####
+Patch_customer_address_without_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Patch_customer_address_with_fake_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses/fake {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Patch_another_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_another_customer_address_by_id_using_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_second_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_no_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers//addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_wrong_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/DE--1/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_empty_required_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": null,"firstName": null,"lastName": null, "address1": null,"address2": null,"zipCode": null,"city": null,"iso2Code": null}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+Patch_customer_address_with_invalid_salutation
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "Fake"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+######DELETE#####
+Delete_customer_address_with_wrong_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Delete_customer_address_with_no_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/positive.robot
new file mode 100644
index 0000000..e906425
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/addresses/positive.robot
@@ -0,0 +1,244 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+#####POST#####
+Create_customer_address_with_all_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_only_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] None
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] None
+ And Response body parameter should be: [data][attributes][phone] None
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+
+
+Create_customer_address_as_shipping_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": true,"isDefaultBilling": false}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_billing_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": true}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+#GET
+Get_empty_list_of_customer_addresses
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ Response should contain the array of a certain size: [data] 0
+
+Get_list_of_customer_addresses_with_1_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] address_uid
+ And Response body parameter should be: [data][0][type] addresses
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][0][attributes][city] ${default.city}
+ And Response body parameter should be: [data][0][attributes][country] ${default.country}
+ And Response body parameter should be: [data][0][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][0][attributes][company] ${default.company}
+ And Response body parameter should be: [data][0][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][0][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][0][attributes][isDefaultBilling] True
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_list_of_customer_addresses_with_2_addresses
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": true,"isDefaultBilling": true}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] first_address_uid
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Save value to a variable: [data][1][id] second_address_uid
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${second_address_uid}
+ ... AND Response status code should be: 204
+
+#DELETE
+Delete_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/addresses
+ ... AND Response status code should be: 200
+ ... AND Response should contain the array of a certain size: [data] 1
+ ... AND Save value to a variable: [data][0][id] address_uid
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+
+
+#PATCH
+Update_customer_address_several_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ ... AND Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${address_uid}
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${changed.address1}
+ And Response body parameter should be: [data][attributes][address2] ${changed.address2}
+ And Response body parameter should be: [data][attributes][address3] ${changed.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${changed.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_access/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_access/positive.robot
new file mode 100644
index 0000000..7a8444c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_access/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+##### all negative and positive tests for this endpoint are already covered with other tests (e.g. abstract-product-prices checks that without token proces are not accessible)
+Get_resources_customer_can_access
+ When I send a GET request: /customer-access
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] customer-access
+ And Response should contain the array of a certain size: [data][0][attributes][resourceTypes] ${restricted_content_qty}
+ And Response body parameter should be: [data][0][attributes][resourceTypes][0] abstract-product-prices
+ And Response body parameter should be: [data][0][attributes][resourceTypes][1] concrete-product-prices
+ And Response body parameter should be: [data][0][attributes][resourceTypes][2] checkout
+ And Response body parameter should be: [data][0][attributes][resourceTypes][3] checkout-data
+ And Response body parameter should be: [data][0][attributes][resourceTypes][4] guest-cart-items
+
+Access_restricted_resource_as_authorized_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_product.product_with_volume_prices.abstract_sku}/abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_volume_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/negative.robot
new file mode 100644
index 0000000..58167fc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/negative.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation_with_wrong_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"39085d16b04b34265910c7ea2a35367ggh"}}}
+ Response status code should be: ${422}
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ And Response should return error code: 423
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":""}}}
+ Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_without_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{}}}
+ Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_type
+ And I send a POST request: /customer-confirmation {"data":{"type":"","attributes":{"registrationKey":"607a17d1c673f461ca40002ea79fddc0"}}}
+ Response status code should be: 400
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_already_used_confirmation_key
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 423
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/positive.robot
new file mode 100644
index 0000000..9daba18
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_confirmation/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot
new file mode 100644
index 0000000..249e7a7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/negative.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_wrong_email_format
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"123"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_empty_email
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":""}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_incorrect_type
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot
new file mode 100644
index 0000000..b222fb8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_forgotten_password/positive.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_with_all_required_fields_and_valid_data
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/negative.robot
new file mode 100644
index 0000000..f3bb0b5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/negative.robot
@@ -0,0 +1,125 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_not_equal_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field newPassword should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_data_type
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_current_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: newPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password_confirmation
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":""}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_non_autorizated_user
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_not_valid_user_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new_additional}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 408
+ And Response should return error message: Invalid password
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_short_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"test","confirmPassword":"test"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_long_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_customer_reference
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/ {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"1234567890123","confirmPassword":"1234567890123"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_mandatory_fields
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/test123 {"data":{"type":"customer-password","attributes":{"newPassword":"${yves_user.password}"}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_invalid_access_token
+ Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/positive.robot
new file mode 100644
index 0000000..212c8b5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_password/positive.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_eighth_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_eighth_user.password}","newPassword":"${yves_eighth_user.password_new}","confirmPassword":"${yves_eighth_user.password_new}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new_additional}"}}}
+ Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new}"}}}
+ And Response status code should be: 201
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/negative.robot
new file mode 100644
index 0000000..dd0c423
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/negative.robot
@@ -0,0 +1,84 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_without_customer_id
+ I send a PATCH request: /customer-restore-password/ {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"fake","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_without_restorePasswordKey
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: restorePasswordKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_confirmation_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"${yves_user.password}","confirmPassword":""}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_short_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"test","confirmPassword":"test"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_long_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_not_equal_new_password_and_confirm_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 406
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_url
+ I send a PATCH request: /customer-restorepassword/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/positive.robot
new file mode 100644
index 0000000..c165361
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customer_restore_password/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_ninth_user.first_name}","lastName":"${yves_ninth_user.last_name}","gender":"${gender.female}","salutation":"${yves_ninth_user.salutation}","email":"random-name1+${random}${email.domain}","password":"${yves_ninth_user.password}","confirmPassword":"${yves_ninth_user.password}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I send a POST request: /customer-forgotten-password {"data": {"type": "customer-forgotten-password","attributes": {"email":"${user_email}"}}}
+ ... AND Save the result of a SELECT DB query to a variable: select restore_password_key from spy_customer where customer_reference = '${user_reference_id}' restore_key
+ When I send a PATCH request: /customer-restore-password/${user_reference_id} {"data":{"type":"customer-restore-password","id":"${user_reference_id}","attributes":{"restorePasswordKey":"${restore_key}","password":"${yves_ninth_user.password_new}","confirmPassword":"${yves_ninth_user.password_new}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${user_email} ${yves_ninth_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/negative.robot
new file mode 100644
index 0000000..33559ba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/negative.robot
@@ -0,0 +1,247 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Create_a_customer_with_already_existing_email
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 400
+ And Response should return error message: If this email address is already in use, you will receive a password reset link. Otherwise you must first validate your e-mail address to finish registration. Please check your e-mail.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_short_password
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"Test12!","confirmPassword":"Test12!","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_long_password
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_equal_passwords
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"1234567890123","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_accepted_terms_and_coditions
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":false}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_type
+ I send a POST request: /customers/ {"data":{"type":"","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":false}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_values_for_required_fields
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":""}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_absent_type
+ I send a POST request: /customers/ {"data":{"attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_wrong_email_format
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"test.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_missing_required_fields
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Array in response should contain property with value: [errors] detail acceptedTerms => This field is missing.
+ And Array in response should contain property with value: [errors] detail gender => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_wrong_gender
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/DE35
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_cusomer_without_access_token
+ I send a GET request: /customers/DE35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_customer_with_access_token_from_another_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_second_user.reference}
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/DE--30 {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":false}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_absent_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_invalid_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_without_access_token
+ I send a PATCH request: /customers/DE--35 {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_cusomer_without_access_token
+ I send a DELETE request: /customers/DE--35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/DE35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_with_access_token_from_another
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/DE--30
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/positive.robot
new file mode 100644
index 0000000..764a3da
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/customer_endpoints/customers/positive.robot
@@ -0,0 +1,118 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Create_customer
+ When I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"random-name2+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] user_reference_id
+ And Save value to a variable: [data][attributes][email] user_email
+ And Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${user_reference_id}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${user_email}
+ And Response body parameter should be: [data][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ [Teardown] Run Keywords I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${user_email} ${yves_user.password_new}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+New_customer_can_login_after_confirmation
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"random-name3+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I get access token for the customer: ${user_email} ${yves_user.password_new}
+ And I set Headers: Authorization=${token}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Get_customer_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ And Response body has correct self link internal
+
+Update_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_second_user.first_name}","lastName":"${yves_second_user.last_name}","gender":"${gender.male}","salutation":"${yves_second_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 200
+ And Response body has correct self link internal
+ And I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][gender] ${gender.male}
+ [Teardown] Run Keywords I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 200
+ ... AND Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+
+Get_customer_array_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/
+ And Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] customers
+ And Response body parameter should be: [data][0][id] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][0][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][0][attributes][updatedAt]
+
+Delete_customer
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"random-name4+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${user_email} ${yves_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${user_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/negative.robot
new file mode 100644
index 0000000..9870957
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/negative.robot
@@ -0,0 +1,135 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+
+####### POST #######
+
+Adding_not_existing_voucher_code_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "419901","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "1111111"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Adding_voucher_code_that_could_not_be_applied_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "464012","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Adding_voucher_code_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request: /carts/invalidCartId/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Adding_voucher_without_access_token
+ [Setup] Get voucher code by discountId from Database: 3
+ When I send a POST request: /carts/fake/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+
+Adding_voucher_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "419901","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization="fake"
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+Deleting_voucher_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "419901","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=
+ When I send a DELETE request: /carts/${cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Deleting_voucher_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "419901","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization="fake"
+ When I send a DELETE request: /carts/${cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Deleting_voucher_code_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a DELETE request: /carts/invalidCartId/vouchers/${discount_voucher_code}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/positive.robot
new file mode 100644
index 0000000..8dc88ae
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/discount_endpoints/vouchers/positive.robot
@@ -0,0 +1,163 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+#####POST#####
+Adding_voucher_code_to_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${discount.products_cost_with_discounts.voucher_concrete_product_1_with_brand_safescan_2_items}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ #checking cart rule and vouchers in cart
+ And Response body parameter should contain: [data][attributes][discounts][0][displayName] ${discount.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Checking_voucher_is_applied_after_order_is_placed
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan}","quantity": 2, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Response body parameter with rounding should be: [included][0][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ #calculatedDiscounts - "10% off Safescan" discount
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculatedDiscounts]["${discount.id_4.name}"]
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts]["${discount.id_4.name}"][displayName] ${discount.id_4.name}
+ VAR ${discount_total_sum} ${discount.products_cost_with_discounts.voucher_concrete_product_1_with_brand_safescan_2_items}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts]["${discount.id_4.name}"][sumAmount] ${discount_total_sum}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts]["${discount.id_4.name}"][voucherCode] ${discount_voucher_code}
+
+
+Adding_two_vouchers_with_different_priority_to_the_same_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan_and_white_color}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 3
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ And Save value to a variable: [data][attributes][discounts][0][code] voucher_1
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Get voucher code by discountId from Database: 4
+ And I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ And Save value to a variable: [data][attributes][discounts][0][code] voucher_2
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][2]
+ And Response should contain the array of a certain size: [data][attributes][discounts] 3
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${discount.products_cost_with_discounts.voucher_concrete_product_1_with_brand_safescan_2_items}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ #calculatedDiscounts - "10% off Safescan" discount
+ And Response body parameter should contain: [data][attributes][discounts][0][displayName] ${discount.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${voucher_2}
+ #calculatedDiscounts - "5% off White" discount
+ And Response body parameter should contain: [data][attributes][discounts][1][displayName] ${discount.id_3.name}
+ And Response body parameter should contain: [data][attributes][discounts][1][code] ${voucher_1}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Adding_voucher_with_cart_rule_with_to_the_same_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan}","quantity": 10}}}
+ ... AND Response status code should be: 201
+ ... AND Get voucher code by discountId from Database: 4
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ #discountTotal
+ And Save value to a variable: discount_total_sum ${discount.products_cost_with_discounts.voucher_concrete_product_1_with_brand_safescan_2_items}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ #checking cart rule and vouchers in cart
+ And Response body parameter should contain: [data][attributes][discounts][0][displayName] ${discount.id_4.name}
+ And Response body parameter should contain: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response body parameter should contain: [data][attributes][discounts][1][displayName] ${discount.cart_rule_name_10_off_minimum_order}
+ And Response body parameter should contain: [data][attributes][discounts][1][code] None
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+Deleting_voucher_from_cart_of_logged_in_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount.concrete_products_with_discounts.concrete_product_with_brand_safescan_and_white_color}","quantity": 5}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][totals][grandTotal] grand_total
+ ... AND Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ ... AND Get voucher code by discountId from Database: 4
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cartId}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /carts/${cartId}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total}
+ And Response body parameter should NOT be: [data][attributes][discounts][0][displayName] ${discount.id_4.name}
+ And Response body parameter should NOT be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/negative.robot
new file mode 100644
index 0000000..6d05f3d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-labels
+
+*** Test Cases ***
+Get_product_label_with_invalid_label_id
+ When I send a GET request: /product-labels/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_with_nonexistend_label_id
+ When I send a GET request: /product-labels/3001
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_without_label_id
+ When I send a GET request: /product-labels
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1202
+ And Response should return error message: Product label id is missing.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/positive.robot
new file mode 100644
index 0000000..3f506e9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_labels/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue alternative-products product product-labels discontinued-products
+
+*** Test Cases ***
+Get_manual_product_label_by_id
+ When I send a GET request: /product-labels/${label_manual.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_manual.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_manual.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_new_product_label_by_id
+ When I send a GET request: /product-labels/${label_new.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_new.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_new.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_sale_product_label_by_id
+ When I send a GET request: /product-labels/${label_sale.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_sale.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_sale.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_discontinued_product_label_by_id
+ When I send a GET request: /product-labels/${label_discontinued.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_discontinued.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_discontinued.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_alternative_product_label_by_id
+ When I send a GET request: /product-labels/${label_alternative.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_alternative.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_alternative.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/negative.robot
new file mode 100644
index 0000000..9048a76
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_an_attribute_with_non_existent_attribute_id
+ When I send a GET request: /product-management-attributes/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4201
+ And Response should return error message: Attribute not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/positive.robot
new file mode 100644
index 0000000..ca58d85
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_management_attributes/positive.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_all_product_management_attributes
+ When I send a GET request: /product-management-attributes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 50
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-management-attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes][key]
+ And Response body parameter should not be EMPTY: [data][0][attributes][inputType]
+ And Response body parameter should not be EMPTY: [data][0][attributes][allowInput]
+ And Response body parameter should be in: [data][0][attributes][allowInput] True False
+ And Response body parameter should be in: [data][0][attributes][isSuper] True False
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][value]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][localizedValues]
+ And Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] localeName ${locale.DE.name} ${locale.EN.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][localizedValues][0][translation]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain property with value in: [data] [attributes][allowInput] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isSuper] True False
+ And Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] localeName ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][localizedKeys] translation
+ And Each array element of nested array should contain property with value NOT in: [data] [attributes][localizedKeys] translation None
+ And Each array element of array in response should contain nested property: [data] [attributes] values
+ And Each array element of array in response should contain nested property: [data] [attributes][values] value
+ And Each array element of array in response should contain nested property: [data] [attributes][values] localizedValues
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_product_management_attribute_by_id_superattribute
+ When I send a GET request: /product-management-attributes/${product_management_superattribute_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_superattribute_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_superattribute_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] True
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][localeName]
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][translation]
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management_attribute_free_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_attribute_free_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_attribute_free_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_non_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management_attribute_no_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_attribute_no_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_attribute_no_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/negative.robot
new file mode 100644
index 0000000..5c073c7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/negative.robot
@@ -0,0 +1,98 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+
+*** Test Cases ***
+Get_a_review_with_non_existent_review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Product review is not found.
+
+Get_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_review_by_id_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews/78
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_a_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews/78
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Create_a_product_review_without_token
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Create_a_product_review_with_invalid_token
+ [Setup] I set Headers: Authorization=fake
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_a_product_review_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-review","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_a_product_review_with_missing_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_a_product_review_with_empty_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": "","nickname": "","summary": "","description": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail rating => This value should be greater than or equal to 1.
+ And Array in response should contain property with value: [errors] detail summary => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail nickname => This value should not be blank.
+
+Create_a_product_review_with_missing_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This field is missing.
+ And Array in response should contain property with value: [errors] detail summary => This field is missing.
+ And Array in response should contain property with value: [errors] detail nickname => This field is missing.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/positive.robot
new file mode 100644
index 0000000..816215c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_reviews/positive.robot
@@ -0,0 +1,89 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+
+*** Test Cases ***
+#Get Request
+Get_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_product.product_with_reviews.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] rating
+ And Each array element of array in response should contain nested property: [data] [attributes] nickname
+ And Each array element of array in response should contain nested property: [data] [attributes] summary
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_a_subset_of_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][0][attributes][rating]
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Get_product_reviews_for_product_with_no_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_availability.abstract_available_with_stock_and_never_out_of_stock}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_product_review_by_id
+ [Setup] Run Keywords I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ ... AND Save value to a variable: [data][0][id] review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/${review_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_product.product_with_reviews.qty}
+ And Response body parameter should be: [data][id] ${review_id}
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][attributes][rating]
+ And Response body parameter should have datatype: [data][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Create_a_product_review
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_options.abstract_sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 202
+ And Response reason should be: Accepted
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] review_id
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should be: [data][attributes][rating] ${review.default_rating}
+ And Response body parameter should be: [data][attributes][nickname] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][summary] ${review.title}
+ And Response body parameter should be: [data][attributes][description] ${review.text}
+ And Response body has correct self link for created entity: ${review_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/negative.robot
new file mode 100644
index 0000000..be7a9aa
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_a_tax_set_with_concrete_sku
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.concrete_available_product.sku}/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
+
+Get_a_tax_set_with_missing_sku
+ When I send a GET request: /abstract-products//product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_a_tax_set_with_non_existing_sku
+ When I send a GET request: /abstract-products/fake/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/positive.robot
new file mode 100644
index 0000000..d9bf457
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/product_tax_sets/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_product_tax sets
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-tax-sets
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response should contain the array larger than a certain size: [data][0][attributes][restTaxRates] 1
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] name
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] rate
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] country
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/negative.robot
new file mode 100644
index 0000000..e61d903
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Get_related_products_without_abstract_SKU
+ When I send a GET request: /abstract-products//related-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_related_products_for_nonexistent_SKU
+ When I send a GET request: /abstract-products/not_a_SKU/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_related_products_for_concrete_SKU
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.concrete_available_product.sku}/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/positive.robot
new file mode 100644
index 0000000..accde6c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/related_products/positive.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Product_has_related_products
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.abstract_sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_with_related_relations.has_related_products.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_with_related_relations.has_related_products.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_with_related_relations.has_related_products.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes][brand]
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array of a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames][brand]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributes] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeNames] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Product_has_related_products_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.abstract_sku}/related-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-prices][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-image-sets][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][concrete-products][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][abstract-product-availabilities][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-tax-sets][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 0
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+
+Product_has_no_related_products
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/negative.robot
new file mode 100644
index 0000000..b39f47e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/negative.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+No_cart_is_passing_to_upselling_products_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Nonexistent_cart_id_is_passing_to_upselling_products_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_invalid token
+ [Setup] I set Headers: Authorization=invalid
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_upselling_products_without_access_token
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_upselling_products_using_cart_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/positive.robot
new file mode 100644
index 0000000..8e02cbe
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/general_product_endpoints/upselling_products/positive.robot
@@ -0,0 +1,443 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Cart_contains_product_with_upselling_relation
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${product_related_product_with_upselling_relation.merchant_reference}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should be: [data][0][attributes][description] ${product_related_product_with_upselling_relation.description}
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array of a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_abstract_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-prices][data] type
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-prices][data] id
+ And Response body parameter should be: [included][0][type] abstract-product-prices
+ And Response body parameter should be: [included][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response include should contain certain entity type: abstract-product-prices
+ And Each array element of array in response should contain property with value: [included] type abstract-product-prices
+ And Each array element of array in response should contain nested property: [included] attributes price
+ And Each array element of array in response should contain nested property: [included] attributes prices
+ And Each array element of array in response should contain nested property: [included] [attributes][prices] priceTypeName
+ And Response body parameter should be: [included][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_abstract_prodcut_image_sets
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-image-sets][data] type
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-image-sets][data] id
+ And Response body parameter should be: [included][0][type] abstract-product-image-sets
+ And Response body parameter should be: [included][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type abstract-product-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes imageSets
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] name
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets] images
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlLarge
+ And Each array element of array in response should contain nested property: [included] [attributes][imageSets][0][images] externalUrlSmall
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships][concrete-products][data] type
+ And Each array element of array in response should contain nested property: [data] [relationships][concrete-products][data] id
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][attributes][sku] ${product_related_product_with_upselling_relation.concrete_available_product.sku}
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDiscontinued]
+ And Response body parameter should be: [included][0][attributes][discontinuedNote] None
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should have datatype: [included][0][attributes][reviewCount] int
+ And Response body parameter should be: [included][0][attributes][productAbstractSku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [included][0][attributes][name] ${product_related_product_with_upselling_relation.concrete_available_product.name}
+ And Response body parameter should be: [included][0][attributes][description] ${product_related_product_with_upselling_relation.concrete_available_product.description}
+ And Response body parameter should be: [included][0][attributes][metaTitle] ${product_related_product_with_upselling_relation.concrete_available_product.meta_title}
+ And Response body parameter should be: [included][0][attributes][metaKeywords] ${product_related_product_with_upselling_relation.concrete_available_product.meta_keywords}
+ And Response body parameter should be: [included][0][attributes][metaDescription] ${product_related_product_with_upselling_relation.concrete_available_product.meta_description}
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [attributes] sku
+ And Each array element of array in response should contain nested property: [included] [attributes] isDiscontinued
+ And Each array element of array in response should contain nested property: [included] [attributes] discontinuedNote
+ And Each array element of array in response should contain nested property: [included] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [included] [attributes] reviewCount
+ And Each array element of array in response should contain nested property: [included] [attributes] productAbstractSku
+ And Each array element of array in response should contain nested property: [included] [attributes] name
+ And Each array element of array in response should contain nested property: [included] [attributes] description
+ And Each array element of array in response should contain nested property: [included] [attributes] attributes
+ And Each array element of array in response should contain nested property: [included] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [included] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [included] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [included] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [included] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [included] [links] self
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_abstract_product_availabilities
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-availabilities][data] type
+ And Each array element of array in response should contain nested property: [data] [relationships][abstract-product-availabilities][data] id
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property with value: [included] [type] abstract-product-availabilities
+ And Each array element of array in response should contain nested property: [included] [attributes] quantity
+ And Each array element of array in response should contain nested property with value: [included] [attributes][availability] True
+ And Each array element of array in response should contain nested property: [included] [attributes] availability
+ And Each array element of array in response should contain nested property: [included] [attributes] quantity
+ And Each array element of array in response should contain nested property: [included] [links] self
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_product_labels
+ [Setup] Run Keywords Trigger product labels update
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: product-labels
+ And Each array element of array in response should contain nested property with value: [included] [type] product-labels
+ And Each array element of array in response should contain nested property: [included] [attributes] name
+ And Each array element of array in response should contain nested property: [included] [attributes] isExclusive
+ And Each array element of array in response should contain nested property: [included] [attributes] position
+ And Each array element of array in response should contain nested property: [included] [attributes] frontEndReference
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${label_new.id}
+ And Response body parameter should be: [included][0][attributes][name] ${label_new.name}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_product_tax_sets
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: product-tax-sets
+ And Each array element of array in response should contain nested property with value: [included] [type] product-tax-sets
+ And Each array element of array in response should contain nested property: [included] [attributes] name
+ And Each array element of array in response should contain nested property: [included] [attributes][restTaxRates] name
+ And Each array element of array in response should contain nested property: [included] [attributes][restTaxRates] rate
+ And Each array element of array in response should contain nested property: [included] [attributes][restTaxRates] country
+ And Each array element of array in response should contain nested property: [included] [links] self
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_product_options
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [included] 4
+ And Each array element of array in response should contain nested property: [data] [relationships][product-options][data] type
+ And Each array element of array in response should contain nested property: [data] [relationships][product-options][data] id
+ And Response body parameter should be: [data][0][relationships][product-options][data][0][id] ${concrete_of_product_with_relations_upselling.product_options.OP_1.id}
+ And Response body parameter should be: [data][0][relationships][product-options][data][1][id] ${concrete_of_product_with_relations_upselling.product_options.OP_2.id}
+ And Response body parameter should be: [data][0][relationships][product-options][data][2][id] ${concrete_of_product_with_relations_upselling.product_options.OP_3.id}
+ And Response body parameter should be: [data][0][relationships][product-options][data][3][id] ${concrete_of_product_with_relations_upselling.product_options.OP_insurance.id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: product-options
+ And Each array element of array in response should contain nested property: [included] attributes optionGroupName
+ And Each array element of array in response should contain nested property: [included] attributes sku
+ And Each array element of array in response should contain nested property: [included] attributes optionName
+ And Each array element of array in response should contain nested property: [included] attributes price
+ And Each array element of array in response should contain nested property: [included] attributes currencyIsoCode
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${concrete_of_product_with_relations_upselling.product_options.OP_1.id}
+ And Response body parameter should be: [included][0][attributes][optionGroupName] ${concrete_of_product_with_relations_upselling.product_options.OP_1.option_group_name}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_of_product_with_relations_upselling.product_options.OP_1.sku}
+ And Response body parameter should be: [included][0][attributes][optionName] ${concrete_of_product_with_relations_upselling.product_options.OP_1.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][1][id] ${concrete_of_product_with_relations_upselling.product_options.OP_2.id}
+ And Response body parameter should be: [included][1][attributes][optionGroupName] ${concrete_of_product_with_relations_upselling.product_options.OP_2.option_group_name}
+ And Response body parameter should be: [included][1][attributes][sku] ${concrete_of_product_with_relations_upselling.product_options.OP_2.sku}
+ And Response body parameter should be: [included][1][attributes][optionName] ${concrete_of_product_with_relations_upselling.product_options.OP_2.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][2][id] ${concrete_of_product_with_relations_upselling.product_options.OP_3.id}
+ And Response body parameter should be: [included][2][attributes][optionGroupName] ${concrete_of_product_with_relations_upselling.product_options.OP_3.option_group_name}
+ And Response body parameter should be: [included][2][attributes][sku] ${concrete_of_product_with_relations_upselling.product_options.OP_3.sku}
+ And Response body parameter should be: [included][2][attributes][optionName] ${concrete_of_product_with_relations_upselling.product_options.OP_3.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ And Response body parameter should be: [included][3][id] ${concrete_of_product_with_relations_upselling.product_options.OP_insurance.id}
+ And Response body parameter should be: [included][3][attributes][optionGroupName] ${concrete_of_product_with_relations_upselling.product_options.OP_insurance.option_group_name}
+ And Response body parameter should be: [included][3][attributes][sku] ${concrete_of_product_with_relations_upselling.product_options.OP_insurance.sku}
+ And Response body parameter should be: [included][3][attributes][optionName] ${concrete_of_product_with_relations_upselling.product_options.OP_insurance.option_name}
+ And Each array element of array in response should contain property with value in: [included] [attributes][currencyIsoCode] ${currency.eur.code} ${currency.dollar.code}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_product_reviews
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [included] 9
+ And Response body parameter should be in: [data][3][relationships][product-reviews][data][0][id] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.id}
+ And Response body parameter should be in: [data][4][relationships][product-reviews][data][0][id] ${concrete_of_product_with_relations_upselling.product_reviews.review_5.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: product-reviews
+ And Each array element of array in response should contain nested property: [included] attributes rating
+ And Each array element of array in response should contain nested property: [included] attributes nickname
+ And Each array element of array in response should contain nested property: [included] attributes summary
+ And Each array element of array in response should contain nested property: [included] attributes description
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be in: [included][0][id] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.id}
+ And Response body parameter should be in: [included][0][attributes][rating] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.rating}
+ And Response body parameter should be in: [included][0][attributes][nickname] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.nickname}
+ And Response body parameter should be in: [included][0][attributes][summary] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.summary}
+ And Response body parameter should be in: [included][0][attributes][description] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.description}${concrete_of_product_with_relations_upselling.product_reviews.review_9.description}
+ And Response body parameter should be in: [included][3][id] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.id}
+ And Response body parameter should be in: [included][3][attributes][rating] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.rating}
+ And Response body parameter should be in: [included][3][attributes][nickname] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.nickname}
+ And Response body parameter should be in: [included][3][attributes][summary] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.summary}
+ And Response body parameter should be in: [included][3][attributes][description] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.description}${concrete_of_product_with_relations_upselling.product_reviews.review_9.description}
+ And Response body parameter should be in: [included][8][id] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.id} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.id}
+ And Response body parameter should be in: [included][8][attributes][rating] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.rating} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.rating}
+ And Response body parameter should be in: [included][8][attributes][nickname] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.nickname} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.nickname}
+ And Response body parameter should be in: [included][8][attributes][summary] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.summary} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.summary}
+ And Response body parameter should be in: [included][8][attributes][description] ${concrete_of_product_with_relations_upselling.product_reviews.review_1.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_2.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_3.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_4.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_5.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_6.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_7.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_8.description} ${concrete_of_product_with_relations_upselling.product_reviews.review_9.description}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_product_with_upselling_relation_with_include_category_nodes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be: [data][0][relationships][category-nodes][data][0][id] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_25.id}
+ And Response body parameter should be: [data][0][relationships][category-nodes][data][1][id] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_23.id}
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response include should contain certain entity type: category-nodes
+ And Each array element of array in response should contain nested property: [included] attributes nodeId
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes metaTitle
+ And Each array element of array in response should contain nested property: [included] attributes metaKeywords
+ And Each array element of array in response should contain nested property: [included] attributes metaDescription
+ And Each array element of array in response should contain nested property: [included] attributes isActive
+ And Each array element of array in response should contain nested property: [included] attributes order
+ And Each array element of array in response should contain nested property: [included] attributes url
+ And Each array element of array in response should contain nested property: [included] attributes children
+ And Each array element of array in response should contain nested property: [included] attributes parents
+ And Response body parameter should be: [included][0][id] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_25.id}
+ And Response body parameter should be: [included][0][attributes][name] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_25.name}
+ And Response body parameter should be: [included][1][id] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_23.id}
+ And Response body parameter should be: [included][1][attributes][name] ${concrete_of_product_with_relations_upselling.category_nodes.category_node_23.name}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_multiple_products_with_upselling_relation
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_related_products.concrete_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_available_product.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Cart_contains_no_products_with_upselling_relations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_available_product.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_upselling_products_for_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name":"Cart-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/negative.robot
new file mode 100644
index 0000000..0b91899
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/negative.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+
+*** Test Cases ***
+Retrieves_merchant_addresses_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-addresses
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-addresses
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/positive.robot
new file mode 100644
index 0000000..73db3f8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_addresses/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+*** Test Cases ***
+Retrieves_merchant_addresses
+ When I send a GET request: /merchants/${merchants.computer_experts.merchant_id}/merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should be: [data][0][type] merchant-addresses
+ And Response body parameter should be: [data][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [data][0][attributes][addresses][0][city] ${merchants.computer_experts.addresses.city_munchen}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-addresses
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address2
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] longitude
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Retrieves_merchant_with_include_merchant_addresses
+ When I send a GET request: /merchants/${merchants.computer_experts.merchant_id}?include=merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchants.computer_experts.merchant_id}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should have datatype: [data][relationships] dict
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-addresses]
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-addresses
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] longitude
+ And Response body parameter should be: [included][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [included][0][attributes][addresses][0][city] ${merchants.computer_experts.addresses.city_munchen}
+ And Response body parameter should be: [included][0][attributes][addresses][0][address1] ${merchants.computer_experts.addresses.address1}
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/negative.robot
new file mode 100644
index 0000000..b20b119
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-opening-hours
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-opening-hours
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/positive.robot
new file mode 100644
index 0000000..1d0fc2c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchant_opening_hours/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours
+ When I send a GET request: /merchants/${merchants.computer_experts.merchant_id}/merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should be: [data][0][type] merchant-opening-hours
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-opening-hours
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][weekdaySchedule] list
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][dateSchedule] list
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] noteGlossaryKey
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_merchant_with_include_merchant_opening_hours
+ When I send a GET request: /merchants/${merchants.computer_experts.merchant_id}?include=merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchants.computer_experts.merchant_id}
+ And Response should contain the array of a certain size: [included][0][attributes][weekdaySchedule] 8
+ And Response should contain the array of a certain size: [included][0][attributes][dateSchedule] 154
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-opening-hours]
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-opening-hours
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] noteGlossaryKey
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][day] MONDAY
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeFrom] 07:00:00.000000
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeTo] 13:00:00.000000
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][date] 2024-01-01
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][noteGlossaryKey] "New Years Day"
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/negative.robot
new file mode 100644
index 0000000..c66670d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/negative.robot
@@ -0,0 +1,14 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant
+
+
+
+*** Test Cases ***
+Retrieves_merchant_by_non_exist_id
+ When I send a GET request: /merchants/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/positive.robot
new file mode 100644
index 0000000..aec4760
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/merchant_endpoints/merchants/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieves_list_of_merchants
+ When I send a GET request: /merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchants
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantName
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonRole
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonFirstName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonLastName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] logoUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] publicEmail
+ And Each array element of array in response should contain nested property: [data] [attributes] publicPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] bannerUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] deliveryTime
+ And Each array element of array in response should contain nested property: [data] [attributes] faxNumber
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] terms
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] cancellationPolicy
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] imprint
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] dataPrivacy
+ And Each array element of array in response should contain nested property: [data] [attributes] categories
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_a_merchant_by_id
+ When I send a GET request: /merchants/${merchants.computer_experts.merchant_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][id] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][attributes][merchantName] ${merchants.computer_experts.merchant_name}
+ And Response body parameter should be: [data][attributes][merchantUrl] ${merchants.computer_experts.merchant_url}
+ And Response body parameter should be: [data][attributes][contactPersonRole] ${merchants.computer_experts.contact_person_role}
+ And Response body parameter should be: [data][attributes][contactPersonTitle] ${merchants.computer_experts.contact_person_title}
+ And Response body parameter should be: [data][attributes][contactPersonFirstName] ${merchants.computer_experts.contact_person_first_name}
+ And Response body parameter should be: [data][attributes][contactPersonLastName] ${merchants.computer_experts.contact_person_last_name}
+ And Response body parameter should be: [data][attributes][contactPersonPhone] ${merchants.computer_experts.contact_person_phone}
+ And Response body parameter should be: [data][attributes][publicEmail] ${merchants.computer_experts.public_email}
+ And Response body parameter should be: [data][attributes][publicPhone] ${merchants.computer_experts.public_phone}
+ And Response body parameter should be: [data][attributes][description] ${merchants.computer_experts.description}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][logoUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][bannerUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][deliveryTime]
+ And Response body parameter should not be EMPTY: [data][attributes][faxNumber]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][terms]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][cancellationPolicy]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][imprint]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][dataPrivacy]
+ And Response body parameter should have datatype: [data][attributes][categories] list
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/negative.robot
new file mode 100644
index 0000000..3277300
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue navigation spryker-core
+
+*** Test Cases ***
+Get_navigations_by_non_exist_id
+ When I send a GET request: /navigations/testNonExistNavigations
+ Then Response status code should be: 404
+ And Response should return error code: 1601
+ And Response should return error message: Navigation not found.
+
+
+
+Get_absent_navigations
+ When I send a GET request: /navigations
+ Then Response status code should be: 400
+ And Response should return error code: 1602
+ And Response should return error message: Navigation id not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/positive.robot
new file mode 100644
index 0000000..eec0497
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/navigations_endpoints/navigations/positive.robot
@@ -0,0 +1,69 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core navigation category-management merchant-category
+
+*** Test Cases ***
+Get_navigation_tree_using_valid_navigation_key
+ When I send a GET request: /navigations/MAIN_NAVIGATION
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][isActive] bool
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] children
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][nodeType] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][title] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][children] list
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][nodeType]
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][title]
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] children
+ And Response body has correct self link internal
+
+Get_navigation_tree_using_valid_navigation_key_with_category_nodes_included
+ When I send a GET request: /navigations/MAIN_NAVIGATION?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Should Contain The Array Larger Than a Certain Size: [included] 0
+ And Response Should Contain The Array Larger Than a Certain Size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][category-nodes]
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] type
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ Each array element of array in response should contain nested property: [included] [links] self
+ And Each Array Element Of Array In Response Should Contain Property With Value: [included] type category-nodes
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes nodeId
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes name
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaTitle
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaKeywords
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaDescription
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes isActive
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes order
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes url
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes children
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes parents
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/negative.robot
new file mode 100644
index 0000000..9261c2f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/negative.robot
@@ -0,0 +1,92 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags glue order-management marketplace-order-management spryker-core customer-access
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_order_by_order_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_with_invalid_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/fake_order_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+
+Get_order_by_order_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+Get_customer_orders_list_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_customer_orders_list_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_customer_orders_list_with_invalid_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/yves_user.reference/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/positive.robot
new file mode 100644
index 0000000..601ab79
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/orders_endpoints/positive.robot
@@ -0,0 +1,582 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout order-management marketplace-order-management marketplace-product merchant product product-bundles marketplace-packaging-units measurement-units packaging-units non-splittable-products shipment marketplace-shipment configurable-bundle configurable-product gift-cards spryker-core customer-access
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should be: [data][attributes][merchantReferences][0] ${product_related_product_with_upselling_relation.merchant_reference}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [data][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][items][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be: [data][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [data][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_different_items_and_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_id_1
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 2, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][1][id] concrete_product_id_2
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}", "paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_id_1}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete_product_id_2}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be: [data][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be: [data][attributes][items][2][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][2][quantity] 1
+
+Get_order_by_order_id_with_nonsplit_item
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 10, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 1
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 10
+
+Get_order_by_order_id_with_mode.net_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 20, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 2},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.chf.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 20
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_2}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.chf.code}
+
+Get_order_by_order_id_with_split_shipment
+ [Documentation] bug https://spryker.atlassian.net/browse/CC-21273
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_id_1
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][1][id] concrete_product_id_2
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}", "paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_id_1}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product_id_2}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response body parameter should not be EMPTY: [data][attributes][shipments][0][shipmentMethodName]
+ And Response body parameter should not be EMPTY: [data][attributes][shipments][0][carrierName]
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shipments][1][shipmentMethodName]
+ And Response body parameter should not be EMPTY: [data][attributes][shipments][1][carrierName]
+ And Response body parameter should be: [data][attributes][shipments][1][deliveryTime] 0
+ And Response body parameter should be: [data][attributes][shipments][1][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][1][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][1][currencyIsoCode] ${currency.eur.code}
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_split_shipment_&_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_id_1
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_options.concrete_sku}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][1][id] concrete_product_id_2
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}", "paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_id_1}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${concrete_product_id_2}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}?include=order-shipments
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be: [data][attributes][items][0][name] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${abstract_product.product_with_options.concrete_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${abstract_product.product_with_options.concrete_sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value: [data][relationships][order-shipments][data] type order-shipments
+ And Each array element of array in response should contain property: [data][relationships][order-shipments][data] id
+ And Response should contain the array of a certain size: [included] 2
+ #included 1
+ And Response body parameter should be: [included][0][type] order-shipments
+ And Response body parameter should be greater than: [included][0][id] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][itemUuids][0]
+ And Response body parameter should be: [included][0][attributes][methodName] ${shipment.method_name_2}
+ And Response body parameter should be: [included][0][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][requestedDeliveryDate] ${shipment.delivery_date}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][0][links]
+ #included 2
+ And Response body parameter should be: [included][1][type] order-shipments
+ And Response body parameter should be greater than: [included][1][id] 0
+ And Response body parameter should not be EMPTY: [included][1][attributes][itemUuids][0]
+ And Response body parameter should be: [included][1][attributes][methodName] ${shipment.method_name_3}
+ And Response body parameter should be: [included][1][attributes][carrierName] ${shipment.carrier_name_1}
+ And Response body parameter should be: [included][1][attributes][requestedDeliveryDate] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address1] ${changed.address1}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address2] ${changed.address2}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address3] ${changed.address3}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][phone] ${changed.phone}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][1][links]
+
+Get_order_by_order_id_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 3, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] ${discount_3.total_sum}
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 30000
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount_3.total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][shipments][0][defaultGrossPrice] ${discount_3.total_sum}
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount: ${discount_3.total_sum}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName: ${discount_3.name}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description: ${discount_3.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 1
+
+Get_order_by_order_id_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_1.sku}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_2.sku}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_3.sku}","quantity": 1, "merchantReference": "${merchants.merchant_office_king_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${discount_concrete_product.product_1.sku}", "${discount_concrete_product.product_2.sku}", "${discount_concrete_product.product_3.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Save value to a variable: [data][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [data][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_concrete_product.product_1.discount_amount_total_sum_of_discounts} + ${discount_concrete_product.product_2.discount_amount_total_sum_of_discounts}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total_sum}
+ #item 1 - "20% off storage" discount and "10% off minimum order" discount
+ And Response should contain the array of a certain size: [data][attributes][items][0][calculatedDiscounts] 2
+ And Response body parameter should be in: [data][attributes][items][0][name] ${discount_concrete_product.product_1.name} ${discount_concrete_product.product_2.name} ${discount_concrete_product.product_3.name}
+ And Response body parameter should be in: [data][attributes][items][0][sku] ${discount_concrete_product.product_1.sku} ${discount_concrete_product.product_2.sku} ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ #item 1 - "20% off storage" discount and "10% off minimum order" discount
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_1.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_1.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [data][attributes][items][0][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][1][quantity] 1
+ #item 2 - "20% off storage" discount
+ And Response should contain the array of a certain size: [data][attributes][items][1][calculatedDiscounts] 2
+ And Response body parameter should be in: [data][attributes][items][1][name] ${discount_concrete_product.product_1.name} ${discount_concrete_product.product_2.name} ${discount_concrete_product.product_3.name}
+ And Response body parameter should be in: [data][attributes][items][1][sku] ${discount_concrete_product.product_1.sku} ${discount_concrete_product.product_2.sku} ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [data][attributes][items][1][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][1][calculatedDiscounts][0][quantity] 1
+ #item 2 - "10% off minimum order" discount
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_2.discount_amount_with_20_percentage_off_storage} ${discount_concrete_product.product_2.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [data][attributes][items][1][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [data][attributes][items][1][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][1][calculatedDiscounts][1][quantity] 1
+ #item 3 - "10% off minimum order" discount
+ And Response should contain the array of a certain size: [data][attributes][items][2][calculatedDiscounts] 1
+ And Response body parameter should be: [data][attributes][items][2][name] ${discount_concrete_product.product_3.name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${discount_concrete_product.product_3.sku}
+ And Response body parameter should be: [data][attributes][items][2][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be: [data][attributes][items][2][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_3.discount_amount_with_10_percentage_off_minimum_order}
+ And Response body parameter should be in: [data][attributes][items][2][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [data][attributes][items][2][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [data][attributes][items][2][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][2][calculatedDiscounts][0][quantity] 1
+ #calculatedDiscounts - "20% off storage" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount: ${discount_1.total_sum_for_discounts_for_products_1_and_2}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName: ${discount_2.name}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description: ${discount_2.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 3
+ #calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount: ${discount_2.total_sum_for_discounts_for_products_1_2_and_3}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName: ${discount_2.name}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description: ${discount_2.description}
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity: 3
+
+Get_customer_orders_list_without_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ When I send a GET request: /orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [expenseTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [discountTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [taxTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [subtotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [grandTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [canceledTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals] [remunerationTotal] int
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+Get_customer_orders_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_customer_orders_list_without_order_id_with_pagination
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference": "${merchants.merchant_spryker_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}", "paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND I send a GET request: /orders
+ ... AND Save value to a variable: [data][2][id] order_id
+ When I send a GET request: /customers/${yves_user.reference}/orders?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] orders
+ And Response body parameter should be: [data][0][id] ${order_id}
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
new file mode 100644
index 0000000..97bb5da
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+Get_not_existing_product_offer_availabilities
+ When I send a GET request: /product-offers/test/product-offer-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_empty_product_offer_availabilities
+ When I send a GET request: /product-offers//product-offer-availabilities
+ Then Response status code should be: 400
+ And Response should return error code: 3702
+ And Response reason should be: Bad Request
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_product_offer_availabilities_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}/product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_not_existing_product_offer_availabilities_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}/product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
new file mode 100644
index 0000000..8c9e9ab
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+Get_product_offer_availabilities
+ When I send a GET request: /product-offers/${second_offer_with_volume_price}/product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] id ${second_offer_with_volume_price}
+ And Each array element of array in response should contain property with value: [data] type product-offer-availabilities
+ And Response should contain the array larger than a certain size: [data][0][attributes][quantity] 0
+ And Each array element of array in response should contain property with value in: [data] [attributes][isNeverOutOfStock] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][availability] True False
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/negative.robot
new file mode 100644
index 0000000..7130a57
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/negative.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_product_offer_prices_without_offer_id
+ When I send a GET request: /product-offers//product-offer-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_product_offers_price_without_complete_url
+ When I send a GET request: /product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 3702
+ And Response reason should be: Bad Request
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_concrete_product_offers_price
+ When I send a GET request: /concrete-products/123456789/product-offers?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+Get_product_offer_with_volume_prices_included_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+Get_product_offer_with_volume_prices_included_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+Get_product_offer_with_volume_prices_included_for_denied_product_offer
+ When I send a GET request: /product-offers/${denied_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_prices_with_invaild_offer_id
+ When I send a GET request: /product-offers/test/product-offer-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/positive.robot
new file mode 100644
index 0000000..77e99de
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offer_prices/positive.robot
@@ -0,0 +1,134 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieve_prices_of_a_product_offer
+ When I send a GET request: /product-offers/${merchants.computer_experts.merchant_offer_id}/product-offer-prices
+ Then Response reason should be: OK
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][id] ${merchants.computer_experts.merchant_offer_id}
+ And Response body parameter should be: [data][0][attributes][price] ${merchants.computer_experts.merchant_offer_price}
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices]
+ And Response body has correct self link
+
+Get_concrete_product_without_offers_prices
+ When I send a GET request: /concrete-products/${bundle_product.concrete.sku}/product-offers?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_all_concrete_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /concrete-products/${abstract_product.product_with_volume_prices.concrete_sku}/product-offers?include=product-offer-prices,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${second_offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offers
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${merchants.merchant_office_king_id}
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should contain: [data][0][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 4
+ And Response should contain the array of a certain size: [data][0][relationships] 2
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: merchants
+ And Response body has correct self link
+
+Get_all_product_offer_info_with_product_offer_prices_and_merchants_included
+ When I send a GET request: /product-offers/${active_offer_with_merchant_sku}?include=product-offer-prices,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer_with_merchant_sku}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.merchant_office_king_id}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantSku]
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: merchants
+
+Get_product_offer_price_without_volume_prices
+ When I send a GET request: /product-offers/${offer_without_volume_price}/product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_without_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices]
+
+Get_product_offer_price_with_gross_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}/product-offer-prices?priceMode=${mode.gross}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][grossAmount] 0
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_price_with_net_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}/product-offer-prices?priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][netAmount] 0
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_price_with_gross_chf
+ When I send a GET request: /product-offers/${offer_with_volume_price}/product-offer-prices?currency=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][grossAmount] 1
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Get_product_offer_price_with_net_chf
+ When I send a GET request: /product-offers/${offer_with_volume_price}/product-offer-prices?currency=${currency.chf.code}&priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/negative.robot
new file mode 100644
index 0000000..96fab7f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/negative.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product
+
+*** Test Cases ***
+Get_product_offers_without_product_offer_id
+ When I send a GET request: /product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 3702
+ And Response reason should be: Bad Request
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_concrete_product_offers
+ When I send a GET request: /concrete-products/123456789/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_product_offer_with_volume_prices_included_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_denied_product_offer
+ When I send a GET request: /product-offers/offer404?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_empty_product_id
+ When I send a GET request: /concrete-products//product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 312
+ And Response reason should be: Bad Request
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/positive.robot
new file mode 100644
index 0000000..142a1b3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/product_offer_endpoints/product_offers/positive.robot
@@ -0,0 +1,151 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_concrete_product_without_offers
+ When I send a GET request: /concrete-products/${bundle_product.concrete.sku}/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_all_concrete_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /concrete-products/${abstract_product.product_with_volume_prices.concrete_sku}/product-offers?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${second_offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offers
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${merchants.merchant_office_king_id}
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should contain: [data][0][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 6
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+ And Response body has correct self link
+
+Get_all_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /product-offers/${active_offer_with_merchant_sku}?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer_with_merchant_sku}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.merchant_office_king_id}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantSku]
+ And Response should contain the array of a certain size: [included] 3
+ And Response should contain the array of a certain size: [data][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+
+Get_product_offer_without_volume_prices
+ When I send a GET request: /product-offers/${offer_without_volume_price}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_without_volume_price}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][volumePrices] 0
+
+Get_product_offer_with_gross_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_net_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}?include=product-offer-prices&priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [included] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_gross_chf_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}?include=product-offer-prices¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Get_product_offer_with_net_chf_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price}?include=product-offer-prices&priceMode=${mode.net}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/return_reasons/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/return_reasons/positive.robot
new file mode 100644
index 0000000..df24272
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/return_reasons/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue return-management marketplace-return-management
+
+*** Test Cases ***
+#GET requests
+Get_return_reason
+ When I send a GET request: /return-reasons
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type return-reasons
+ And Each array element of array in response should contain nested property: [data] [attributes] reason
+ And Response should contain the array of a certain size: [data] ${return_reasons_qty}
+ And Each array element of array in response should contain nested property with value: [data] [id] None
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/negative.robot
new file mode 100644
index 0000000..a1b218a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/negative.robot
@@ -0,0 +1,44 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+
+*** Test Cases ***
+Create_a_return_with_order_is_not_returnable
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] returnableSalesOrderItemUuid
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${returnableSalesOrderItemUuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Retrieves_a_return_with_non_exists_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /returns/fake_returns_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find return by the given return reference."
+ And Response should return error code: 3602
+
+Retrieves_a_return_with_missing_auth_token
+ When I send a GET request: /returns/DE--21-R1
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+Retrieves_list_of_returns_with_missing_auth_token
+ When I send a GET request: /returns
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/positive.robot
new file mode 100644
index 0000000..8ed6ccb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/return_endpoints/returns/positive.robot
@@ -0,0 +1,319 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+
+*** Test Cases ***
+####POST####
+Create_a_return
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1, "merchantReference" : "${merchants.merchant_spryker_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ And Save value to a variable: [data][id] returnId
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response body has correct self link for created entity: ${returnId}
+
+Create_a_return_with_return_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ When I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] returnId
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response should contain the array of a certain size: [data][relationships][return-items][data] 1
+ And Response body parameter should not be EMPTY: [data][relationships][return-items]
+ And Response body parameter should contain: [data][relationships][return-items][data] type
+ And Response body parameter should contain: [data][relationships][return-items][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Response include should contain certain entity type: return-items
+ And Response body parameter should be: [included][0][attributes][orderItemUuid] ${uuid}
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response include element has self link: return-items
+
+####GET####
+Retrieves_list_of_returns
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Response body has correct self link
+
+Retrieves_list_of_returns_included_return_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships] return-items
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] type
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] id
+ And Each array element of array in response should contain nested property with value: [data] [relationships][return-items][data][0][type] return-items
+ And Response include element has self link: return-items
+ And Response include should contain certain entity type: return-items
+ And Response body parameter should be: [included][0][attributes][orderItemUuid] ${uuid}
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response body has correct self link
+
+Retrieves_list_of_returns_included_merchants
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships] merchants
+ And Each array element of array in response should contain nested property: [data] [relationships][merchants][data][0] type
+ And Each array element of array in response should contain nested property: [data] [relationships][merchants][data][0] id
+ And Each array element of array in response should contain nested property with value: [data] [relationships][merchants][data][0][type] merchants
+ And Response include element has self link: merchants
+ And Response include should contain certain entity type: merchants
+ And Response body has correct self link
+
+Retrieves_return_by_id_with_returns_items_included
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][return-items]
+ And Each array element of array in response should contain property: [data][relationships][return-items][data] type
+ And Each array element of array in response should contain property: [data][relationships][return-items][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain nested property: [included] [attributes] uuid
+ And Each array element of array in response should contain property with value: [included] type return-items
+ And Each array element of array in response should contain property with value in: [included] [attributes][orderItemUuid] ${Uuid} ${Uuid}
+ And Each array element of array in response should contain property with value in: [included] [attributes][reason] ${return_reason_damaged} ${return_reason_damaged}
+ And Response body has correct self link internal
+
+Retrieves_return_by_id_for_sales_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data][attributes] merchantReference
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+
+Retrieves_return_by_id_with_merchants_included
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${merchants.computer_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.computer_experts.merchant_id}", "productOfferReference" : "${merchants.computer_experts.merchant_offer_id}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${merchants.computer_experts.concrete_product_with_offer_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.merchant_spryker_id}
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.computer_experts.merchant_id}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchants]
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response include element has self link: merchants
+ And Response include should contain certain entity type: merchants
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/negative.robot
new file mode 100644
index 0000000..fba3575
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/negative.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog
+
+*** Test Cases ***
+Search_without_query_parameter
+ When I send a GET request: /catalog-search?
+ Then Response status code should be: 200
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..2bc7445
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,720 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product
+
+*** Test Cases ***
+
+##### SEARCH PARAMETERS #####
+
+Search_with_empty_search_criteria_all_default_values_check
+ When I send a GET request: /catalog-search?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ #Sorting
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamNames] ${default_qty.sorting_options}
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamLocalizedNames] ${default_qty.sorting_options}
+ And Response body parameter should contain: [data][0][attributes] currentSortParam
+ And Response body parameter should contain: [data][0][attributes] currentSortOrder
+ #Pagination
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][pagination][config][validItemsPerPageOptions] 3
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.middle}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.biggest}
+ #Abstract products
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] prices
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.eur.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ #Filters - category
+ And Response body parameter should contain: [data][0][attributes] valueFacets
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][name] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][localizedName] Categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] ${default_qty.categories}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][isMultiValued] False
+ #Filters - labels
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][name] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][localizedName] Product Labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][isMultiValued] True
+ #Filters - product class
+ And Response body parameter should be in: [data][0][attributes][valueFacets][2][name] Product Class product-class
+ And Response body parameter should be in: [data][0][attributes][valueFacets][2][localizedName] Product Class Product Classes
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] ${default_qty.product_classes}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][isMultiValued] True
+ #Filters - color
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][name] farbe
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][localizedName] Color
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] ${default_qty.colors}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][config][isMultiValued] True
+ #Filters - material
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][name] material
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][localizedName] Material
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] ${default_qty.materials}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][config][isMultiValued] True
+ #Filters - brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][name] brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][localizedName] Brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] ${default_qty.brands}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][config][isMultiValued] False
+ #Filters - rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][name] rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][localizedName] Product Ratings
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][min] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][max] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][isMultiValued] False
+ #Filters - category tree
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] nodeId
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] name
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] docCount
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] children
+ #Selflinks
+ And Response body has correct self link
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_by_attribute_that_does_not_return_products
+ When I send a GET request: /catalog-search?q=fake
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 0
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 0
+ And Response body has correct self link
+
+Search_by_concrete_sku
+ When I send a GET request: /catalog-search?q=${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_abstract_sku
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_full_name
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][4][values] 1
+ And Response body has correct self link
+
+Search_by_name_substring
+ When I send a GET request: /catalog-search?q=USB
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] 2
+ #brand
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_attribute_(brand)
+ When I send a GET request: /catalog-search?q=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][abstractProducts][0][abstractName] ${brand_1}
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][values][0][value] ${brand_1}
+ And Response body has correct self link
+
+Search_by_several_attributes
+ When I send a GET request: /catalog-search?q=${color_3}+${material_3}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 20
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+
+##### FILTERING #####
+
+Filter_by_rating_only_min
+ When I send a GET request: /catalog-search?q=&rating[min]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 20
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.max}
+
+
+Filter_by_rating_only_max
+ When I send a GET request: /catalog-search?q=&rating[max]=${default_rating.min}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_rating.min}
+
+
+Filter_by_rating_Min_max
+ When I send a GET request: /catalog-search?q=&rating[min]=3&rating[max]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 3
+
+Filter_by_brand_one_brand
+ When I send a GET request: /catalog-search?q=&brand=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] ${brand_1}
+ And Response body has correct self link
+
+Filter_by_brand_two_brands
+ When I send a GET request: /catalog-search?q=&brand[]=${brand_2}&brand[]=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 38
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue][0] ${brand_2}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue][1] ${brand_1}
+
+Filter_by_brand_empty_brand
+ When I send a GET request: /catalog-search?q=&brand=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] ${EMPTY}
+ And Response body has correct self link
+
+Filter_by_brand_non_existing_brand
+ When I send a GET request: /catalog-search?q=&brand=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] test123
+ And Response body has correct self link
+
+Filter_by_label_one_label
+ When I send a GET request: /catalog-search?q=&label=${label.manual}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 5
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 5
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] ${label.manual}
+ And Response body has correct self link
+
+Filter_by_label_two_labels
+ When I send a GET request: /catalog-search?q=&label[]=${label.new}&label[]=${label.manual}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 37
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${label.new}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][1] ${label.manual}
+
+Filter_by_label_non_existing_label
+ When I send a GET request: /catalog-search?q=&label[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] test123
+
+Filter_by_label_empty_label
+ When I send a GET request: /catalog-search?q=&label[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${EMPTY}
+
+Filter_by_color_one_color
+ When I send a GET request: /catalog-search?q=&farbe=${color_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 4
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 4
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] ${color_1}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][0] ${default_qty.categories}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][3] ${default_qty.materials}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][5] ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_color_two_colors
+ When I send a GET request: /catalog-search?q=&farbe[]=${color_1}&farbe[]=${color_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 10
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] ${color_1}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][1] ${color_2}
+
+Filter_by_color_non_existing_color
+ When I send a GET request: /catalog-search?q=&farbe[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] test123
+
+Filter_by_color_empty_color
+ When I send a GET request: /catalog-search?q=&farbe[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${EMPTY}
+
+Filter_by_material_one_material
+ When I send a GET request: /catalog-search?q=&material=${material_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 4
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 4
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${material_1}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][0] ${default_qty.categories}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][2] ${default_qty.colors}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][4] ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_material_two_materails
+ When I send a GET request: /catalog-search?q=&material[]=${material_1}&material[]=${material_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 15
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][0] ${material_1}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][1] ${material_2}
+
+Filter_by_material_non_existing_materail
+ When I send a GET request: /catalog-search?q=&material[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][0] test123
+
+Filter_by_material_empty_material
+ When I send a GET request: /catalog-search?q=&material[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][0] ${EMPTY}
+
+Filter_by_valid_main_category
+ When I send a GET request: /catalog-search?q=&category=${category_lvl1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl1.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl1.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][docCount] ${category_lvl1.qty}
+ And Response body parameter should be greater than: [data][0][attributes][categoryTreeFilter][3][children][0][docCount] 0
+ And Response body parameter should be greater than: [data][0][attributes][categoryTreeFilter][3][children][1][docCount] 0
+ And Response body parameter should be greater than: [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount] 0
+ And Response body has correct self link
+
+Filter_by_valid_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl2.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl2.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][docCount] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][0][docCount] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][1][docCount] 0
+ And Response body parameter should be greater than: [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount] 0
+ And Response body parameter should be less than: [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount] ${category_lvl2.qty}
+ And Response body has correct self link
+
+Filter_by_valid_sub_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl3.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl3.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl3.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][docCount] ${category_lvl3.qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][0][docCount] ${category_lvl3.qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][1][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount] ${category_lvl3.qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][3][children][0][children][1][docCount] 0
+ And Response body has correct self link
+
+Search_with_specific_currency
+ When I send a GET request: /catalog-search?q=¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.chf.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+##### PAGINATION AND SORTING #####
+
+Search_set_specific_page_with_default_ipp
+ # here page 4 is selected using offset because 36/12=3 full pages, search shows the next page after the offset
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.default}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 4
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Search_set_specific_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.middle}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 2
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 18
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.middle}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_last_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.biggest}&page[offset]=${total_number_of_products_in_search}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 12
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 12
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+
+Search_set_invalid_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=18&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_sort_by_name_asc
+ When I send a GET request: /catalog-search?q=&sort=name_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] A
+ And Response body has correct self link
+
+Search_sort_by_name_desc
+ When I send a GET request: /catalog-search?q=&sort=name_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] X
+ And Response body has correct self link
+
+Search_sort_by_rating
+ When I send a GET request: /catalog-search?q=&sort=rating
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] rating
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_sku_highest_rating}
+ And Response body has correct self link
+
+
+Search_sort_by_price_asc
+ When I send a GET request: /catalog-search?q=&sort=price_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 50
+ And Response body has correct self link
+
+Search_sort_by_price_desc
+ When I send a GET request: /catalog-search?q=&sort=price_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10000
+ And Response body has correct self link
+
+Search_sort_by_price_filter_query_parameter_and_pagination
+ When I send a GET request: /catalog-search?q=soe&sort=price_desc&brand=${brand_1}&page[limit]=${ipp.middle}&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 18
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 18
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] ${brand_1}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 5000
+
+Search_by_abstract_sku_with_abstract_include
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-products][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract_product_with_alternative.sku}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot
new file mode 100644
index 0000000..a46935c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/search_endpoints/catalog_search_suggestions/positive.robot
@@ -0,0 +1,238 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product discontinued-products
+
+*** Test Cases ***
+#GET requests
+Get_search_suggestions_without_query_parameter
+ When I send a GET request: /catalog-search-suggestions
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_empty_q_parameter
+ When I send a GET request: /catalog-search-suggestions?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_non_existing_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=000000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_discontinued_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_alternative.sku}
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_all_attributes_data
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_alternative.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_alternative.name_lower_case}
+ And Each array element of array in response should contain property: [data][0][attributes][categories] name
+ And Each array element of array in response should contain property: [data][0][attributes][categories] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] url
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][abstractSku]
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][1][abstractSku]
+ And Response body parameter should be: [data][0][attributes][abstractProducts][1][abstractSku] ${alternative_abstract_product.sku}
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] url
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] url
+ And Response body has correct self link
+
+Get_search_suggestions_with_few_symbols
+ When I send a GET request: /catalog-search-suggestions?q=soe
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Each array element of array in response should contain value: [data][0][attributes][completion] soe
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] soe
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_concrete_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_pages
+ When I send a GET request: /catalog-search-suggestions?q=${cms_pages.first_cms_page.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${cms_pages.first_cms_page.name_in_lower_case}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][name] ${cms_pages.first_cms_page.name}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][url] ${cms_pages.first_cms_page.url_en}
+ And Response body has correct self link
+
+Get_search_suggestions_with_category_collection
+ When I send a GET request: /catalog-search-suggestions?q=${category_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][name] ${category_collection_name}
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][url] ${category_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_page_collection
+ When I send a GET request: /catalog-search-suggestions?q=${cms_page_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][name] ${cms_page_collection_name}
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][url] ${cms_page_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_currency
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${brand_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Array element should contain property with value at least once: [data][0][attributes][abstractProducts] price ${${alternative_abstract_product.price_chf}}
+ And Response body has correct self link
+
+Get_search_suggestions_with_color
+ When I send a GET request: /catalog-search-suggestions?q=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${color_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku_and_included_abstract_products
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][type] abstract-products
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][type] abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should be: [included][0][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [included][0][attributes][description] ${abstract_available_product_with_stock.description}
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes][norm]
+ And Response body parameter should be: [included][0][attributes][attributes][stapelbar] No
+ And Response body parameter should be: [included][0][attributes][attributes][preiseinheit] ${price_unit_1}
+ And Response body parameter should be: [included][0][attributes][attributes][reihenverbinder] No
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes][sitzschalenform]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes][rollenausfuehrung]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes][brand]
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributesDefinition] 0
+ And Response body parameter should contain: [included][0][attributes][superAttributes][bezugsfarbe] ${color_4}
+ And Response body parameter should contain: [included][0][attributes][attributeMap][super_attributes][bezugsfarbe] ${color_4}
+ And Response body parameter should contain: [included][0][attributes][attributeMap][product_concrete_ids] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][attribute_variants] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributeMap][attribute_variant_map]
+ And Response body parameter should contain: [included][0][attributes] metaTitle
+ And Response body parameter should be: [included][0][attributes][metaKeywords] ${abstract_available_product_with_stock.concrete_available_product.meta_keywords}
+ And Response body parameter should be: [included][0][attributes][metaDescription] ${abstract_available_product_with_stock.concrete_available_product.meta_description}
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [included][0][attributes][url]
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot
new file mode 100644
index 0000000..bee50bb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/negative.robot
@@ -0,0 +1,791 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shopping-lists marketplace-shopping-lists product bundle-products marketplace-product configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list_without_access_token
+ I send a POST request: /shopping-lists/${1st_shopping_list.id}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Add_a_concrete_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ I send a POST request: /shopping-lists/${1st_shopping_list.id}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Add_a_product_to_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/shoppingListId/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Add_a_product_with_non_existing_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"sku${random}","quantity":1}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1508
+ And Response should return error message: Concrete product not found.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":0}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_negaive_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":-1}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":""}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_too_big_amount_of_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":99999999999999999999}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_abstract_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.abstract.sku}","quantity":1}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1508
+ And Response should return error message: Concrete product not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_sku_value_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"","quantity":1}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_invalid_data_for_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":"test"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_shopping_list_id_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Add_a_concrete_product_to_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+
+Update_product_to_the_shopping_list_without_access_token
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_product_in_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Update_product_in_the_shopping_list_withot_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists//shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_quantity_of_the_product_at_the_shopping_list_to_zero
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":0}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_quntity_at_the_shopping_list_to_non_digit_value
+ [Documentation] Created a new bug CC-22842 as current error message is: "quantity => This value should be less than 2147483647." and not This value should be greater than 0.
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":"test"}}}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_in_the_shopping_list_withot_shopping_list_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/ {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_in_the_shopping_list_without_quantity_in_the_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_in_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_at_the_shopping_list_with_empty_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_product_at_the_shopping_list_without_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Remove_a_product_from_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Remove_a_product_from_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Remove_a_product_with_non_existing_id_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1504
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list item not found.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists//shopping-list-items/shoppingListItemId
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_item_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Remove_a_concrete_product_from_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration_and_configurable_product
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":0,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"fake","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":-2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should not be blank.
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_aconfigurable_product_with_missing_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_aconfigurable_product_with_string_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"string","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":1,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":"True","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot
new file mode 100644
index 0000000..3359696
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_list_items/positive.robot
@@ -0,0 +1,501 @@
+
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shopping-lists marketplace-shopping-lists product bundle-products marketplace-product prices configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_one_more_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_the_same_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_a_bundle_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_unavailable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_product.product_availability.concrete_unavailable_product}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_availability.concrete_unavailable_product}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_bundle_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 3
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][type] shopping-list-items
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][id] ${shoppingListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${shoppingListItemId}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"20.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"20.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"01.01.2025\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_the_quantity_of_the_Configured_Product_so_Volume_price_is_applied
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":6,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 6
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][grossAmount] 165
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][netAmount] 150
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${shoppingListItemId1} ${shoppingListItemId2}
+ And Response body parameter should be in: [included][1][id] ${shoppingListItemId1} ${shoppingListItemId2}
+ And Response body parameter should be in: [included][0][attributes][quantity] 2 1
+ And Response body parameter should be in: [included][1][attributes][quantity] 2 1
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][isComplete] True False
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be less than: [included][1][attributes][quantity] 3
+ And Response body parameter should be greater than: [included][0][attributes][quantity] 0
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] displayData {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] configuration {\"time_of_day\":\"4\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] isComplete True
+ And Response body parameter should be in: [included][1][id] ${shoppingListItemId2} ${shoppingListItemId1}
+ And Response body parameter should be in: [included][0][id] ${shoppingListItemId2} ${shoppingListItemId1}
+ And Response body parameter should be in: [included][1][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku} ${configurable_product.sku}
+ And Response body parameter should be in: [included][0][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku} ${configurable_product.sku}
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot
new file mode 100644
index 0000000..682211a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/negative.robot
@@ -0,0 +1,233 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue shopping-lists marketplace-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Create_a_shopping_list_with_empty_type
+ I send a POST request: /shopping-lists {"data":{"type":"","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_non_autorized_user
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Create_a_shopping_list_with_absent_type
+ I send a POST request: /shopping-lists {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_already_existing_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value: [errors] detail Shopping list with given name already exists.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shopping_list_with_too_long_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value is too long. It should have 255 characters or less.
+
+Delete_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Delete_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a DELETE request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
+
+Delete_a_shopping_list_withouth_shopping_list_id
+ I send a DELETE request: /shopping-lists
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_for_the_customer_with_empty_attribute_section
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+Update_shopping_list_with_existing_name_of_another_available_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND Save value to a variable: [data][1][attributes][name] 2ndShoppingListName
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${2ndShoppingListName}"}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value: [errors] detail Shopping list with given name already exists.
+
+Update_shopping_list_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+
+Update_shopping_list_name_with_too_long_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value is too long. It should have 255 characters or less.
+
+Update_shopping_list_withouth_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/ {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_with_wrong_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_shopping_list_with_non_autorized_user
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Update_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_a_shopping_list_with_absent_type
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_shopping_list_with_invalid_type
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shoppinglists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_shopping_list_with_non_autorized_user
+ I send a GET request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Get_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a GET request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot
new file mode 100644
index 0000000..1a88a7e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/shopping_list_endpoints/shopping_lists/positive.robot
@@ -0,0 +1,217 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue shopping-lists marketplace-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Create_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListId
+ And Save value to a variable: [data][attributes][createdAt] createdAt
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a DELETE request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+
+Update_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name_with_includes
+ [Documentation] bug https://spryker.atlassian.net/browse/CC-16543
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data][relationships][shopping-list-items][data] [type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data][relationships][shopping-list-items][data] [id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_a_shopping_list_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND Save value to a variable: [data][attributes][createdAt] createdAt
+ ... AND Save value to a variable: [data][attributes][updatedAt] updatedAt
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}2"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId2
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] type shopping-lists
+ And Each array element of array in response should contain nested property with datatype: [data] id str
+ And Each array element of array in response should contain nested property with value: [data] [attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][name] str
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][createdAt] str
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][updatedAt] str
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId1}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I send a DELETE request: /shopping-lists/${shoppingListId2}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_shopping_lists_info_with_non_zero_quantity_of_number_of_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${product_related_product_with_upselling_relation.concrete_available_product.sku}","quantity":3}}}
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] 0
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_shopping_lists_info_for_user_with_zero_quantity_of_number_of_shopping_lists
+ [Setup] Run Keywords I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_single_shopping_list_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${abstract_available_product_with_stock.concrete_available_product.sku}","quantity":3}}}
+ ... AND Response status code should be: 201
+ I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data][relationships][shopping-list-items][data] [type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data][relationships][shopping-list-items][data] [id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] [relationships][shopping-list-items][data][0][type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data] [relationships][shopping-list-items][data][0][id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Each array element of array in response should contain nested property with value: [data] type shopping-lists
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][0][relationships] 0
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/negative.robot
new file mode 100644
index 0000000..360c110
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/negative.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+Get_health_check_with_disabled_services
+### Test works only if all services are disabled as default
+ When I send a GET request: /health-check
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 403
+ And Response body parameter should be: [data][0][attributes][message] HealthCheck endpoints are disabled for all applications.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_invalid_service_name
+ When I send a GET request: /health-check?services=sear
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_empty_service_name
+ When I send a GET request: /health-check?services=
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+#Get_health_check_with_non_existing_id
+ #[Documentation] The bug https://spryker.atlassian.net/browse/CC-16492 related to the self link and required ID
+ # When I send a GET request: /health-check/1
+ # Then Response status code should be: 200
+ # And Response reason should be: OK
+ # And Response body parameter should be: [data][type] health-check
+ # And Response body parameter should be: [data][id] None
+ # And Response body parameter should be: [data][attributes][status] healthy
+ # And Response body parameter should be: [data][attributes][statusCode] 200
+ # And Response body parameter should be: [data][attributes][message] None
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][0][name] search
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][1][name] storage
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][2][name] zed-request
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] status True
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] message None
+ ## Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/positive.robot
new file mode 100644
index 0000000..1269f30
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/health_checks/positive.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+#Get_health_check_with_all_enabled_services
+ #When I send a GET request: /health-check
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 3
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][1][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][2][name] zed-request
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] status True
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] message None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_search_service
+ #When I send a GET request: /health-check?services=search
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_storage_service
+ #When I send a GET request: /health-check?services=storage
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_zed_request_service
+ #When I send a GET request: /health-check?services=zed-request
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] zed-request
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..28be8cd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/negative.robot
@@ -0,0 +1,12 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response should return error code: 601
+ And Response should return error message: Store not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..29849d4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/stores/positive.robot
@@ -0,0 +1,122 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_all_available_stores
+ [Tags] dms-off
+ [Documentation] works only for dms-off shop as in dms-on regions don't have timeZone and locale code
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] timeZone
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] code
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_all_available_stores_dms_on
+ [Tags] dms-on
+ [Documentation] works only for dms-off shop as in dms-on regions don't have timeZone and locale code
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ [Tags] dms-off
+ [Documentation] works only for dms-off shop as in dms-on regions don't have timeZone and locale code
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should have datatype: [data][attributes][timeZone] str
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][locales] code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
+
+Get_store_by_id_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/negative.robot
new file mode 100644
index 0000000..353a794
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/negative.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_url_collection_by_empty_url
+ When I send a GET request: /url-resolver
+ Then Response status code should be: ${422}
+ And Response should return error code: 2801
+ And Response should return error message: Url request parameter is missing.
+
+Get_url_collection_when_requested_url_does_not_exist
+ When I send a GET request: /url-resolver?url=/requested/url/does/not/exist/
+ Then Response status code should be: 404
+ And Response should return error code: 2802
+ And Response should return error message: Url not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/positive.robot
new file mode 100644
index 0000000..32970ec
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/utility_endpoints/url_resolver/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_url_collections_by_url_paramater_of_category_nodes
+ When I send a GET request: /url-resolver?url=${url_resolver.category_nodes}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.category_nodes_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.category_nodes_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_product
+ When I send a GET request: /url-resolver?url=${url_resolver.example}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.entity_type}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.entity_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_cms_page
+ When I send a GET request: /url-resolver?url=${url_resolver.cms}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.cms_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.cms_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_merchant_page
+ When I send a GET request: /url-resolver?url=${url_resolver.merchant}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.merchant_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.merchant_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_parameters_returns_id
+ [Documentation] CC-16595 API: ID is missing from url resolver.
+ [Tags] skip-due-to-issue
+ When I send a GET request: /url-resolver?url=${url_resolver.category_nodes}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver.example}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver.cms}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver.merchant}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot
new file mode 100644
index 0000000..eb83c3d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue measurement-units product
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_unit_id
+ When I send a GET request: /product-measurement-units/notexist
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3402
+ And Response should return error message: Product measurement unit not found.
+
+ Get_a_measurement_unit_without_unit_code
+ When I send a GET request: /product-measurement-units/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3401
+ And Response should return error message: Product measurement unit code has not been specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot
new file mode 100644
index 0000000..0c2660b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/product_measurement_units/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue measurement-units product
+
+*** Test Cases ***
+Get_product_measurement_unit_by_id
+ When I send a GET request: /product-measurement-units/${measurement_unit_m}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${measurement_unit_m}
+ And Response body parameter should be: [data][type] product-measurement-units
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][defaultPrecision]
+ And Response body parameter should have datatype: [data][attributes][defaultPrecision] int
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/negative.robot
new file mode 100644
index 0000000..6e374c5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product measurement-units packaging-units marketplace-packaging-units
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_sku
+ When I send a GET request: /concrete-products/fake/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_abstract_sku
+ When I send a GET request: /concrete-products/${abstract_available_product_with_stock.sku}/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_empty_sku
+ When I send a GET request: /concrete-products//sales-units
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/positive.robot
new file mode 100644
index 0000000..0d6f03a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/glue/weight_unit_endpoints/sales_units/positive.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product measurement-units packaging-units marketplace-packaging-units
+
+*** Test Cases ***
+Get_sales_units_for_product_without_sales_units
+ When I send a GET request: /concrete-products/${abstract_available_product_with_stock.concrete_available_product.sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_sales_units
+ When I send a GET request: /concrete-products/${concrete_product_random_weight.sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] ${concrete_product_random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][precision] int
+ And Each array element of array in response should contain nested property with datatype in: [data] [attributes][conversion] int float
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDisplayed] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDefault] True False
+ Response body parameter should be: [data][0][attributes][productMeasurementUnitCode] ITEM
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_measurement_units_include
+ When I send a GET request: /concrete-products/${concrete_product_random_weight.sku}/sales-units?include=product-measurement-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] ${concrete_product_random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Response body has correct self link
+ And Each array element of array in response should contain a nested array of a certain size: [data] [relationships] 1
+ And Response should contain the array of a certain size: [included] ${concrete_product_random_weight.qty_of_units}
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include element has self link: product-measurement-units
+
diff --git a/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..6da845a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found
diff --git a/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..4ff5077
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2b/sapi/utility_endpoints/stores/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_all_available_stores
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/negative.robot
new file mode 100644
index 0000000..d4086b6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/negative.robot
@@ -0,0 +1,396 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_product_abstract_collection_with_invalid_query_parameter:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=test
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+
+Create_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH INVALID CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_correct_child_and_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}, {"fk_tax_set": 1, "attributes": "FOO1", "sku": "FOO1", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR1", "sku": "FOOBAR1"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ And Response body parameter should be: [data][0][sku] FOO1
+ And Response body parameter should be: [data][0][attributes] FOO1
+ ### GET PRODUCT ABSTRACT WITH CHILDREN ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] FOO1
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][id_product] ${id_product}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1310
+ And Response body parameter should be: [0][message] Incomplete Request - missing identifier for `robot-tests-product-abstracts0.robot-tests-products0`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1309
+ And Response body parameter should be: [0][message] Failed to persist the data for `robot-tests-product-abstracts0.robot-tests-products0.sku`. Please verify the provided data and try again. Entry is duplicated.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_country_collection_with_existing_child_entity
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_product_abstract_by_id_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST PRODUCT ABSTRACT ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_product_abstract_collection_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_price_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.id_product_abstract]={"in": ["1","2", "3"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/positive.robot
new file mode 100644
index 0000000..4093b72
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/complex/positive.robot
@@ -0,0 +1,352 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+ Get_product_abstract_collection_with_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Delete dynamic entity configuration in Database: robot-tests-product-prices
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ Trigger p&s
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 215
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Each array element of array in response should contain property: [data] id_product_abstract
+ And Each array element of array in response should contain property: [data] sku
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] id_product
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] fk_product_abstract
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 215
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Get_product_abstract_with_childs_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response body parameter should be: [data][id_product_abstract] 130
+ And Response body parameter should be: [data][sku] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][1][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][2][fk_product_abstract] 130
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Create_and_update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Create_product_abstract_collection_with_two_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH TWO CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}], "robotTestsProductPrices": [{"fk_price_type": 1, "price": 0}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO2
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR2
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ When Save value to a variable: [data][0][robotTestsProductPrices][0][id_price_product] id_price_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][0][robotTestsProductPrices][0][fk_product_abstract] ${id_product_abstract}
+
+ [Teardown] Run Keywords Delete product_price by id_price_product in Database: ${id_price_product}
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Upsert_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract},"attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][approval_status] None
+ And Response body parameter should be: [data][0][new_to] None
+ And Response body parameter should be: [data][0][color_code] None
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_publish_complex_product_with_child_relations:
+ [Documentation] As the tech dept, we need to adjust this test to check in /catalog-search as well.
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-stock-products spy_stock_product 1 {"identifier":"id_stock_product","fields":[{"fieldName":"id_stock_product","fieldVisibleName":"id_stock_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"quantity","fieldVisibleName":"quantity","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_never_out_of_stock","fieldVisibleName":"is_never_out_of_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_stock","fieldVisibleName":"fk_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-localized-attributes spy_product_localized_attributes 1 {"identifier":"id_product_attributes","fields":[{"fieldName":"id_product_attributes","fieldVisibleName":"id_product_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-stores spy_product_abstract_store 1 {"identifier":"id_product_abstract_store","fields":[{"fieldName":"id_product_abstract_store","fieldVisibleName":"id_product_abstract_store","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relations spy_product_relation 1 {"identifier":"id_product_relation","fields":[{"fieldName":"id_product_relation","fieldVisibleName":"id_product_relation","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_relation_type","fieldVisibleName":"fk_product_relation_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_rebuild_scheduled","fieldVisibleName":"is_rebuild_scheduled","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"product_relation_key","fieldVisibleName":"product_relation_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"query_set_data","fieldVisibleName":"query_set_data","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relation-stores spy_product_relation_store 1 {"identifier":"id_product_relation_store","fields":[{"fieldName":"id_product_relation_store","fieldVisibleName":"id_product_relation_store","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_relation","fieldVisibleName":"fk_product_relation","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-products spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-stores spy_price_product_store 1 {"identifier":"id_price_product_store","fields":[{"fieldName":"id_price_product_store","fieldVisibleName":"id_price_product_store","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_currency","fieldVisibleName":"fk_currency","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_price_product","fieldVisibleName":"fk_price_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"gross_price","fieldVisibleName":"gross_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"net_price","fieldVisibleName":"net_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-defaults spy_price_product_default 1 {"identifier":"id_price_product_default","fields":[{"fieldName":"id_price_product_default","fieldVisibleName":"id_price_product_default","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_product_store","fieldVisibleName":"fk_price_product_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-label-product-abstracts spy_product_label_product_abstract 1 {"identifier":"id_product_label_product_abstract","fields":[{"fieldName":"id_product_label_product_abstract","fieldVisibleName":"id_product_label_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_label","fieldVisibleName":"fk_product_label","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-image-sets spy_product_image_set 1 {"identifier":"id_product_image_set","fields":[{"fieldName":"id_product_image_set","fieldVisibleName":"id_product_image_set","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-stores robotTestsProductAbstractStores fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-relations robotTestsProductRelations fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-relations robot-tests-product-relation-stores robotTestsProductRelationStores fk_product_relation id_product_relation
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-price-products robotTestsProductAbstractPriceProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-price-products robot-tests-price-product-stores robotTestsPriceProductStores fk_price_product id_price_product
+ Create dynamic entity configuration relation in Database: robot-tests-price-product-stores robot-tests-price-product-defaults robotTestsPriceProductStoreDefaults fk_price_product_store id_price_product_store
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-categories robotTestsProductAbstractCategories fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-label-product-abstracts robotTestsProductLabelProductAbstracts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-image-sets robotTestsProductImageSets fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-searches robotTestsProductSearch fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-stock-products robotTestsProductStocks fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-localized-attributes robotTestsProductLocalizedAttributes fk_product id_product
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH STOCK ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":2,"approval_status":"approved","attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec","color_code":"#DC2E09","robotTestsProductAbstractProducts":[{"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1 test attributes","is_active":1,"is_quantity_splittable":1,"sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","robotTestsProductSearch":[{"fk_locale":66,"is_searchable":1}, {"fk_locale":46,"is_searchable":1}],"robotTestsProductStocks":[{"fk_stock":1,"is_never_out_of_stock":1,"quantity":10}],"robotTestsProductLocalizedAttributes":[{"fk_locale":66,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}],"robotTestsProductAbstractStores":[{"fk_store":1}],"robotTestsProductRelations":[{"fk_product_relation_type":1,"is_active":1,"is_rebuild_scheduled":1,"product_relation_key":"Prk-d04e93a4-29ea-4c48-96ab-e87416aefbec","query_set_data":"","robotTestsProductRelationStores":[{"fk_store":1}]}],"robotTestsProductAbstractPriceProducts":[{"fk_price_type":1,"price":1000,"robotTestsPriceProductStores":[{"fk_currency":93,"fk_store":1,"gross_price":9999,"net_price":8999,"robotTestsPriceProductStoreDefaults":[{}]}]}],"robotTestsProductAbstractCategories":[{"fk_category":5,"product_order":16}],"robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"},{"fk_locale":46,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"}],"robotTestsProductLabelProductAbstracts":[{"fk_product_label":1}],"robotTestsProductImageSets":[{"fk_locale":66,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}]}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Save value to a variable: [data][0][sku] abstract_sku
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][sku] concrete_sku
+ Trigger p&s
+ Trigger p&s
+ Trigger p&s
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /abstract-products/${abstract_sku}/abstract-product-availabilities
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] d04e93a4-29ea-4c48-96ab-e87416aefbec
+
+ I set Headers: Content-Type=application/vnd.api+json Accept=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /concrete-products/${concrete_sku}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ And Response body parameter should be: [data][attributes][sku] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-searches?filter[product-searches.fk_product]=${id_product}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][0][id_product_search] id_product_search_first
+ And Save value to a variable: [data][1][id_product_search] id_product_search_second
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-searches {"data": [{"id_product_search": ${id_product_search_first},"is_searchable": 0}, {"id_product_search": ${id_product_search_second},"is_searchable": 0}]}
+ Then Response status code should be: 200
+ Trigger p&s
+ Trigger p&s
+ [Teardown] Run Keywords Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductSearch
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductStocks
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductImageSets
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLabelProductAbstracts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractCategories
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStoreDefaults
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractPriceProducts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelationStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelations
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-image-sets
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-label-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-categories
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-defaults
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relation-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relations
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
+ ... AND Delete dynamic entity configuration in Database: robot-tests-stock-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/negative.robot
new file mode 100644
index 0000000..189c3a1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/negative.robot
@@ -0,0 +1,451 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_list_of_country_with_invalid_token
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID TOKEN ###
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_prefix
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE PREFIX ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity-invalid/robot-test-countries
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE NAME ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/invalid-resource
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/countries/9999999
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_body
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY BODY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_json
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY JSON ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {"data": []}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_valid_and_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}, {"iso2_code":"XX", "iso3_code":"XXX", "name":"Country XXX"}]}
+ Then Response status code should be: 201
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ And Response body parameter should contain: [data][0][iso2_code] XX
+ And Response body parameter should contain: [data][0][iso3_code] XXX
+ When Save value to a variable: [data][0][id_country] country_id
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID RESOURCE NAME ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/cnt {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 404
+ And Response body parameter should contain: [0][message] Not found
+ And Response body parameter should be: [0][code] 007
+ And Response body parameter should contain: [0][status] 404
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_field_value
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID FIELD VALUE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"X","iso3_code":"XXXX","name":""}]}
+ Then Response status code should be: 400
+ And Response should contain the array of a certain size: $ 3
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should contain: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries0` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should contain: [1][status] 400
+ And Response body parameter should contain: [2][message] Invalid data value `robot-test-countries0` for field: `name`.
+ And Response body parameter should be: [2][code] 1306
+ And Response body parameter should contain: [2][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: X
+
+Create_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url", "fk_locale": 46}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] XXA
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] XXB
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XXXX"}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_collection_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY COLLECTION WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XXXX"},{"id_country":${xxb_country_id},"iso3_code":"XXXXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries1` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should be: [1][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field_type
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID FILELD TYPE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name": "FOO", "iso2_code":1234, "iso3_code": 1234}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data type `robot-test-countries0` for field `iso2_code`
+ And Response body parameter should be: [0][code] 1305
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Upsert_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### UDATE WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/1000 {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Entity `robot-test-countries0.id_country: 1000` not found by identifier, and new identifier can not be persisted. Please update the request.
+ And Response body parameter should be: [0][code] 1308
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Delete_country_by_id_is_deletable_false:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": false,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_is_deletable_null:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": null,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_without_is_deletable:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/positive.robot
new file mode 100644
index 0000000..5793370
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/dynamic_entity/positive.robot
@@ -0,0 +1,579 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/api_dynamic_entity_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_country_collection
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 6
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] iso3_code ZMB
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_Collection_with_filter_first_item
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER FIRST ITEM ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=AC
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=UA
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_multiple_filter_fields
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}&filter[countries.postal_code_mandatory]=1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter_in_condition
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code AE
+ And Array in response should contain property with value: [data] iso3_code ARE
+ And Array in response should contain property with value: [data] name United Arab Emirates
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_invalid_multiple_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"], "not in": ["AT"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=234&page[limit]=2
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property: [data] iso2_code
+ And Each array element of array in response should contain property: [data] iso3_code
+ And Each array element of array in response should contain property: [data] name
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations_out_of_items
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS OUT OF ITEMS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=500&page[limit]=10
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+
+Get_country_collection_with_short_configuration
+ ### SETUP DYNAMIC ENTITY CONFIGURATION WITH LESS NUMBER OF FIELDS ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH SHORT CONFIGURATION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 3
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_by_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request with data: /token 'grantType=password&username=admin@spryker.com&password=change123'
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+ When Save value to a variable: [access_token] token
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should not be EMPTY: [data][iso2_code]
+ And Response body parameter should not be EMPTY: [data][iso3_code]
+ And Response body parameter should not be EMPTY: [data][name]
+ And Response body parameter should not be EMPTY: [data][postal_code_mandatory]
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_and_update_country:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XM
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XM","iso3_code":"XXM","name":"POST XM"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XM
+ And Response body parameter should be: [data][0][iso3_code] XXM
+ And Response body parameter should be: [data][0][name] POST XM
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ ### UPDATE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ ### UPDATE ONE FIELD OF COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name":"Test Country"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Test Country
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Test Country
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XM
+
+Create_and_update_url:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST URL AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: /test-url/123
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"/test-url/123", "fk_locale": 46}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][url] /test-url/123
+ And Response body parameter should be: [data][0][fk_locale] 46
+ When Save value to a variable: [data][0][id_url] id_url
+ ### UPDATE URL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls/${id_url} {"data":{"url":"/test-url-test/42"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ And Response body parameter should be: [data][id_url] ${id_url}
+ ### GET URL AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-urls/${id_url}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: /test-url-test/42
+
+Create_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Create_country_collection_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Upsert_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ Delete country by iso2_code in Database: XL
+ Delete country by iso2_code in Database: XS
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XAA","name":"PUT XAA"},{"iso2_code":"XB","iso3_code":"XBB","name":"PUT XBB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] PUT XAA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] PUT XBB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ When Save value to a variable: [data][0][id_country] xaa_country_id
+ When Save value to a variable: [data][1][id_country] xbb_country_id
+
+ ## UPSERT ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ ### PARTIAL UPDATE ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXL"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Country XXL
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXL
+ ### UPSERT COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xaa_country_id},"iso2_code":"XL","iso3_code":"XXL","name":"XXL"},{"id_country":${xbb_country_id},"iso2_code":"XS","iso3_code":"XXS","name":"XXS"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XL
+ And Response body parameter should be: [data][0][iso3_code] XXL
+ And Response body parameter should be: [data][0][name] XXL
+ And Response body parameter should be: [data][0][id_country] ${xaa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XS
+ And Response body parameter should be: [data][1][iso3_code] XXS
+ And Response body parameter should be: [data][1][name] XXS
+ And Response body parameter should be: [data][1][id_country] ${xbb_country_id}
+ ### GET COUNTRIES AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XL
+ And Response body parameter should be: [data][iso3_code] XXL
+ And Response body parameter should be: [data][name] XXL
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xbb_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XS
+ And Response body parameter should be: [data][iso3_code] XXS
+ And Response body parameter should be: [data][name] XXS
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XL
+ ... AND Delete country by iso2_code in Database: XS
+
+Delete_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_country_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][0][iso2_code] XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_id
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] ${xxa_iso2_code}
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `robot-test-countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Authorization_by_x_api_key
+ [Documentation] data excahnge api should support 2 autorization options: by x-api-key and by backoffice user token.
+ [Setup] Create api key in db
+ When I set Headers: x-api-key=${dummy_api_key}
+ And I send a GET request: /dynamic-entity/categories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ [Teardown] Delete api key from db
+
+Availability_recalculation_after_stock_update
+ [Documentation] checks that product availability is recalculated after stock update via data exchange api
+ [Setup] Find first available product via data exchange api
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/stock-products/${index} {"data":{"is_never_out_of_stock":false,"quantity":0}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][is_never_out_of_stock] False
+ And Response body parameter should be: [data][quantity] 0
+ Trigger p&s
+ And Product availability status should be changed on: is_available=False
+ [Teardown] Run Keywords Remove Tags *
+ ... AND Set Tags bapi
+ ... AND Restore product initial stock via data exchange api:
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot
new file mode 100644
index 0000000..8ad515a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/negative.robot
@@ -0,0 +1,127 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Retrieve_push_notification_providers_without_authorization
+ When I set Headers: Content-Type=application/vnd.api+json
+ And I send a GET request: /push-notification-providers
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_push_notification_providers_with_incorrect_token
+ When I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer incorrect_token
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Retrieve_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a GET request: /push-notification-providers/non-existent-id
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+Create_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+
+Create_push_notification_provider_without_authorization
+ When I set Headers: Content-Type=application/vnd.api+json
+ And I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Create_push_notification_provider_with_invalid_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "invalid-type","attributes": {"name": "Invalid Type Push Notification Provider"}}}
+ Then Response status code should be: 400
+ And Response should return error message: Validation issues during the creation
+
+Create_two_push_notification_providers_with_same_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_256_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNamesadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5007
+ And Response should return error message: A push notification provider name must have length from 1 to 255 characters.
+
+Update_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider_with_incorrect_auth
+ [Setup] Run Keywords I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer invalid
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider Updated"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a PATCH request: /push-notification-providers/non-existent-uuid {"data": {"type": "push-notification-providers","attributes": {"name": "Non-Existent Push Notification Provider Updated"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+ Update_push_notification_provider_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id_2} {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Delete_push_notification_provider_with_not_exist_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ Then I send a DELETE request: /push-notification-providers/invalid
+ Then Response status code should be: 404
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot
new file mode 100644
index 0000000..58ca51d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_providers/positive.robot
@@ -0,0 +1,141 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Create_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ And Response body has correct self link for created entity: ${push_notification_provider_id}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_255_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][attributes][name] testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider Updated ${random}"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider Updated ${random}
+ And Response body has correct self link internal
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Retrieve_push_notification_providers
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 200
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should be: [data][1][type] push-notification-providers
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][uuid]
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_pagination
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ # And I send a DELETE request: /push-notification-providers/${push_notification_provider_uuid}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification1${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification2${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?page[offset]=1&page[limit]=1
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should be: [data][0][attributes][name] My-Push-Notification1${random}
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_sorting
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "A-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "B-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?sort=-name
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][name] web-push-php
+ And Response body parameter should be: [data][1][attributes][name] B-My-Push-Notification
+ And Response body parameter should be: [data][2][attributes][name] A-My-Push-Notification
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_by_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ When I send a GET request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Delete_push_notification_provider_while_push_notification_subscription_exists
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # create a provider for push notification
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Save value to a variable: [data][attributes][name] push_notification_provider_name
+ # create a subscription
+ Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_provider_name}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ # delete a provider for push notification
+ De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Then I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 400
+ And Response should return error code: 5004
+ And Response should return error message: Unable to delete push notification provider while push notification subscription exists.
+ [Teardown] Run Keywords Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
new file mode 100644
index 0000000..f948cba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_incorrect_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"DU_AE"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Provided locale not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
new file mode 100644
index 0000000..8eaf279
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_correct_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] ${locale.DE.name}
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses[0].uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+
+Creates_push_notification_subscription_without_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"}}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] None
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses[0].uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/negative.robot
new file mode 100644
index 0000000..44ac8ac
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/negative.robot
@@ -0,0 +1,159 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_Point_Address_Without_Authentication
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
+
+Create_Service_Point_Address_With_Incorrect_Token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer IncorrectToken
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_Duplicate_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5417
+ And Response should return error message: A service point address for the service point already exists.
+
+Create_Service_Point_address_without_address
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+
+Create_Service_Point_address_with_empty_address
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+
+Create_Service_Point_address_with_not_existing_region
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"regionUuid": "not-existing-rigion-uuid", "countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5410
+ And Response should return error message: Region with uuid 'not-existing-rigion-uuid' does not exist for country with iso2 code 'DE'.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_address_with_not_existing_country
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-45${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "NOTEXIST", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5409
+ And Response should return error message: Country with iso2 code 'DE' does not exist.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+ Create_Service_Point_address_with_zip_more_than_15
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-22111111111112", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5415
+ And Response should return error message: A service point address zip code must have length from 1 to 15 characters.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_Address_Without_Authentication
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850 in response 400, expected 403
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=
+ When I send a PATCH request: /service-points/${spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
+
+Update_Service_Point_Address_With_Incorrect_Token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=IncorrectToken
+ When I send a PATCH request: /service-points/${spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Update_Nonexistent_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/not-existing-service-point/service-point-addresses/NonexistentID {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Service point address entity was not found.
+
+Update_Service_Point_Address_Invalid_Content_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "invalid", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 404
+
+Update_Service_Point_Address_Nonexistent_Service_Point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/NonexistentID/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
+Update_Service_Point_Address_Invalid_Region
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"regionUuid": "InvalidRegion", "address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5410
+
+Update_Service_Point_Address_Empty_Zip_Code
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5415
+ And Response should return error message: A service point address zip code must have length from 4 to 15 characters.
+
+Retrieve_address_for_Nonexistent_Service_Point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-points/NonexistentID/service-point-addresses
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
+Read_Service_Point_Address_No_Authentication
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a GET request: /service-points/${spryker_main_store.uuid}/service-point-addresses
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/positive.robot
new file mode 100644
index 0000000..2996bc1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_point_addresses/positive.robot
@@ -0,0 +1,94 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №22","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][attributes][address1] Park Avenue
+ And Response body parameter should be: [data][attributes][address2] Building №22
+ And Response body parameter should be: [data][attributes][zipCode] 30-221
+ And Response body parameter should be: [data][attributes][city] Dreamtown
+ And Response body has correct self link for created entity: ${service_point_address_id}
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_Address_with_address_3
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-2${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][attributes][address3] address3
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_Address_with_region_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-3${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ And Create region in DB: 60 DE Germany 123456789
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"regionUuid":"123456789","address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][attributes][regionUuid] 123456789
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-update-4${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type": "service-point-addresses","attributes":{"regionUuid":"123456789", "countryIso2Code": "DE", "address1": "Park Avenue", "address2": "Building №2", "address3": "7th floor", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ When I send a PATCH request: /service-points/${service_point_id}/service-point-addresses/${service_point_address_id} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address","address2": "new address2", "address3": "new address3", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][attributes][regionUuid] 123456789
+ And Response body parameter should be: [data][attributes][address1] New Address
+ And Response body parameter should be: [data][attributes][address2] new address2
+ And Response body parameter should be: [data][attributes][address3] new address3
+ And Response body parameter should be: [data][attributes][zipCode] 40-123
+ And Response body parameter should be: [data][attributes][city] New City
+ And Response body has correct self link internal
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Retrieve_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-points/${spryker_main_store.uuid2}/service-point-addresses
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][type] service-point-addresses
+ And Response body parameter should be: [data][0][id] ${service_point_address.uuid2}
+ And Response body parameter should be: [data][0][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][0][attributes][uuid] ${service_point_address.uuid2}
+ And Response body parameter should be: [data][0][attributes][address1] ${service_point_address.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${service_point_address.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${service_point_address.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${service_point_address.zip}
+ And Response body parameter should be: [data][0][attributes][city] ${service_point_address.city}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/negative.robot
new file mode 100644
index 0000000..0aa63c8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/negative.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_No_Auth
+ And Create service point in DB uuid=262feb9d-33a7${random} name=TestSP${random} key=sp11${random} isActive=true storeName=DE
+ Then Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType${random} key=sp11${random}
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random} ", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Service_Invalid_Auth
+ Create service point in DB uuid=262feb9d-33a7${random} name=TestSP1${random} key=sp11${random} isActive=true storeName=DE
+ Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType1${random} key=sp11${random}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random}", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Service_By_ID__No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2${random} key=sp11${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2${random} key=sp11${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ And I send a GET request: /services/262feb1fd22067e${random}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Nonexistent_Service
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services/nonexistent_id
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: The service entity was not found.
+
+Get_Services_No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2a${random} key=sp11a${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2a${random} key=sp11a${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ When I send a GET request: /services
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Duplicate_Service_Point_Service_Relation
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Points ${random}","key": "some-service-point-news-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ Create service type in DB uuid=36796774${random} name=TestTypeNewQ${random} key=test-key-goes-here${random}
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service2-point-1-collects${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "new-key2${random}"}}}
+ When Response status code should be: 400
+ And Response should return error code: 5429
+ And Response should return error message: A service with defined relation of service point and service type already exists.
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${36796774${random}}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/positive.robot
new file mode 100644
index 0000000..013e957
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_points/positive.robot
@@ -0,0 +1,122 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+*** Test Cases ***
+Get_All_Service_Points
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point 1","key": "some-service-point1-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Save value to a variable: [data][attributes][key] service_point_key1
+ And Save value to a variable: [data][id] service_point_id1
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point 2","key": "some-service-point2-${random}","isActive": "false","stores": ["AT"]}}}
+ Then Save value to a variable: [data][attributes][key] service_point_key2
+ And Save value to a variable: [data][id] service_point_id2
+ When I send a GET request: /service-points
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][type] service-points
+ And Each array in response should contain property with NOT EMPTY value: [data] [id]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][key]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][isActive]
+ And Each array element of array in response should contain property with value in: [data] [attributes][stores] DE AT
+ [Teardown] Run Keywords Deactivate service point via BAPI ${service_point_id1}
+ ... AND Deactivate service point via BAPI ${service_point_id1}
+
+Get_Services_List
+ [Setup]
+ Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services
+ Then Response status code should be: 200
+ And Array in response should contain property with value: [data] type services
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][1][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: data[0][attributes][isActive] True
+ And Response body parameter should be: data[1][attributes][isActive] True
+ And Response body parameter should be in: data[0][attributes][key] s1 s2
+ And Response body parameter should be in: data[1][attributes][key] s1 s2
+ And Response body has correct self link
+
+Create_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ And Response body has correct self link for created entity: ${service_id}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Update_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point new ${random}","key": "some-service-point-new-key-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ # #update a service
+ When I send a PATCH request: /services/${service_id} {"data": {"type": "services", "attributes": {"isActive": "false"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Get_Service_By_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new1-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service1 ${random}", "key": "service1-test1${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collecta${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a GET request: /services/${service_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][id]
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/negative.robot
new file mode 100644
index 0000000..8ed50f4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/negative.robot
@@ -0,0 +1,143 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_Type_With_Maximum_Length_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "dsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374333asss"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5420
+ And Response should return error message: A service type key must have length from 1 to 255 characters.
+
+Create_Service_Type_With_256_Length_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "dsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374333asss", "key": "service1-test${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5422
+ And Response should return error message: A service type name must have length from 1 to 255 characters.
+
+Create_Duplicate_Service_Type_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=with-duplicate-key name=Duplicate key key=with-duplicate-key
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Another Service 2 ${random}", "key": "with-duplicate-key"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5419
+ And Response should return error message: A service type with the same key already exists.
+ [Teardown] Delete service type in DB with-duplicate-key
+
+Create_Service_Type_With_Duplicate_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=with-duplicate-name${random} name=Duplicate Service key=with-duplicate-name${random}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Duplicate Service", "key": "another-key${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5425
+ And Response should return error message: A service type with the same name already exists.
+ [Teardown] Delete service type in DB with-duplicate-name${random}
+
+Create_Service_Type_With_Empty_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Invalid Key Length", "key": ""}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5420
+ And Response should return error message: A service type key must have length from 1 to 255 characters.
+
+Create_Service_Type_With_Empty_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "", "key": "invalid-name-length"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5422
+ And Response should return error message: A service type name must have length from 1 to 255 characters.
+
+Create_Service_Type_without_Auth
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 403
+
+Create_Service_Type_with_incorrect_Auth
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer incorrect
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 401
+
+Update_Service_Type_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=update-service-type-key${random} name=update-service-type-key key=update-service-type-key${random}
+ When I send a PATCH request: /service-types/update-service-type-key${random} {"data": {"type": "service-types", "attributes": {"key": "new-key"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5423
+ And Response should return error message: The service type key is immutable.
+ [Teardown] Delete service type in DB update-service-type-key${random}
+
+Update_Not_Existing_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-types/not-existing-service-type {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name ${random}","key": "original-key${random}"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5418
+ And Response should return error message: The service type entity was not found.
+
+Update_Service_Type_with_incorrect_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=serv-ty${random} name=New Service key=serv-ty${random}
+ When I send a PATCH request: /service-types/serv-ty${random} {"data": {"type": "incorrect-types", "attributes": {"name": "Updated Service", "key": "serv-ty${random}"}}}
+ Then Response status code should be: 400
+ [Teardown] Delete service type in DB serv-ty${random}
+
+Update_Service_Type_without_Auth
+ When Create service type in DB 12345678${random} test test
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a PATCH request: /service-types/12345678${random} {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name","key": "12345678${random}"}}}
+ Then Response status code should be: 403
+ [Teardown] Delete service type in DB 12345678${random}
+
+Get_Service_Types_No_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /service-types
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+
+Get_Service_Types_Invalid_Auth
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer InvalidToken
+ When I send a GET request: /service-types
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_Service_Type_By_ID_No_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ Create service type in DB uuid=service-by-id${random} name=service-by-id key=service-by-id${random}
+ When I send a GET request: /service-types/service-by-id${random}
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+ [Teardown] Delete service type in DB service-by-id${random}
+
+Get_Service_Type_By_ID_invalid_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ Create service type in DB uuid=service-invalid${random} name=service-invalid key=service-invalid${random}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer InvalidToken
+ When I send a GET request: /service-types/service-invalid${random}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Delete service type in DB service-invalid${random}
+
+Get_Nonexistent_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-types/nonexistent_id
+ Then Response status code should be: 404
+ And Response should return error code: 5418
+ And Response should return error message: The service type entity was not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/positive.robot
new file mode 100644
index 0000000..03fd4ce
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/service_types/positive.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Test Service ${random}
+ And Response body parameter should be: [data][attributes][key] service1-test${random}
+ And Response body has correct self link for created entity: ${service_type_id}
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Update_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "original-key${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ When I send a PATCH request: /service-types/${service_type_id} {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name","key": "original-key${random}"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Updated Service Name
+ And Response body parameter should be: [data][attributes][key] original-key${random}
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Get_Service_Type_by_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Collect Service${random}", "key": "collect${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ When I send a GET request: /service-types/${service_type_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Collect Service${random}
+ And Response body parameter should be: [data][attributes][key] collect${random}
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Get_Service_Types_List
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "S_type${random}", "key": "s_type${random}"}}}
+ And Save value to a variable: [data][id] service_type_id
+ When I send a GET request: /service-types
+ Then Response status code should be: 200
+ And Array in response should contain property with value: [data] type service-types
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should be in: data[0][attributes][name] Pickup S_type${random}
+ And Response body parameter should be in: data[1][attributes][name] Pickup S_type${random}
+ And Response body parameter should be in: data[0][attributes][key] pickup s_type${random}
+ And Response body parameter should be in: data[0][attributes][key] pickup s_type${random}
+ [Teardown] Delete service type in DB ${service_type_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/negative.robot
new file mode 100644
index 0000000..a688e08
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/negative.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Create_Service_No_Auth
+ And Create service point in DB uuid=262feb9d-33a7${random} name=TestSP${random} key=sp11${random} isActive=true storeName=DE
+ Then Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType${random} key=sp11${random}
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random} ", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Service_Invalid_Auth
+ Create service point in DB uuid=262feb9d-33a7${random} name=TestSP1${random} key=sp11${random} isActive=true storeName=DE
+ Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType1${random} key=sp11${random}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random}", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Service_By_ID__No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2${random} key=sp11${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2${random} key=sp11${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ And I send a GET request: /services/262feb1fd22067e${random}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Nonexistent_Service
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services/nonexistent_id
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: The service entity was not found.
+
+Get_Services_No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2a${random} key=sp11a${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2a${random} key=sp11a${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ When I send a GET request: /services
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Duplicate_Service_Point_Service_Relation
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Points ${random}","key": "some-service-point-news-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ Create service type in DB uuid=36796774${random} name=TestTypeNewQ${random} key=test-key-goes-here${random}
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service2-point-1-collects${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "new-key2${random}"}}}
+ When Response status code should be: 400
+ And Response should return error code: 5429
+ And Response should return error message: A service with defined relation of service point and service type already exists.
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${36796774${random}}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/positive.robot
new file mode 100644
index 0000000..e29967d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/services/positive.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Get_Services_List
+ [Setup]
+ Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services
+ Then Response status code should be: 200
+ And Array in response should contain property with value: [data] type services
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][1][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: data[0][attributes][isActive] True
+ And Response body parameter should be: data[1][attributes][isActive] True
+ And Response body parameter should be in: data[0][attributes][key] s1 s2
+ And Response body parameter should be in: data[1][attributes][key] s1 s2
+ And Response body has correct self link
+
+Create_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ And Response body has correct self link for created entity: ${service_id}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Update_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ # #update a service
+ When I send a PATCH request: /services/${service_id} {"data": {"type": "services", "attributes": {"isActive": "false"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Get_Service_By_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new1-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service1 ${random}", "key": "service1-test1${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collecta${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a GET request: /services/${service_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][id]
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/teardown/service_points_teardown.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/teardown/service_points_teardown.robot
new file mode 100644
index 0000000..6ce323d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/service_points/teardown/service_points_teardown.robot
@@ -0,0 +1,9 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+
+*** Test Cases ***
+Delete_all_non-default_service_points_from_DB_with_p&s
+ Delete all non-default service points from DB with p&s
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/negative.robot
new file mode 100644
index 0000000..e17c393
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/negative.robot
@@ -0,0 +1,149 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/shipment_type_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Create_shipment_type_with_incorrect_type_in_body
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5845
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "incorrect-type","attributes": {"name": "Some Shipment Type","key": "wrong-type${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 55020
+ And Response should return error message: Unknown error.
+
+Create_shipment_type_with_empty_body
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {}
+ Then Response status code should be: 400
+ And Response should return error code: 55020
+ And Response should return error message: Unknown error.
+
+Create_shipment_type_with_empty_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "empty_token${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Create_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "incorrect_token${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Create_shipment_type_without_key_in_request
+ [Documentation] https://spryker.atlassian.net/browse/CC-32473 Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Create_shipment_type_with_empty_key_in_request
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type ${random}","key": "","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5503
+ And Response should return error message: A delivery type key must have a length from 1 to 255 characters.
+
+Create_shipment_type_with_already_used_key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "existing-shipment-type-key","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "existing-shipment-type-key","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5502
+ And Response should return error message: A delivery type with the same key already exists.
+ [Teardown] Delete shipment type in DB: existing-shipment-type-key
+
+Update_shipment_type_without_token
+ I set Headers: Content-Type=${default_header_content_type}
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Update_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Update_shipment_type_without_key
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310 Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Update_shipment_type_with_empty_key
+ [Documentation] https://spryker.atlassian.net/browse/CC-32473 Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "name${random}","key": "","isActive": "true","stores": ["DE"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Update_sipment_type_with_not_existing_key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types/not-existing-key
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Retrieve_single_shipment_type_without_auth
+ When I set Headers: Content-Type=${default_header_content_type}
+ And I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_single_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=wrong_token
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Retrieve_single_shipment_type_with_incorrect_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /shipment-types/incorrect_id
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Retrieve_list_of_shipment_types_without_auth
+ I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /shipment-types/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_list_of_shipment_types_witt_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/positive.robot
new file mode 100644
index 0000000..5b4859c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/shipment_types/positive.robot
@@ -0,0 +1,167 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/shipment_type_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Create_shipment_type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type ${random}","key": "some-shipment-type-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] shipment-types
+ And Save value to a variable: [data][id] shipment_type_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] Some Shipment Type ${random}
+ And Response body parameter should be: [data][attributes][key] some-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link for created entity: ${shipment_type_id}
+ [Teardown] Delete shipment type in DB: some-shipment-type-${random}
+
+Create_new_shipment_type_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "not_unique_name","key": "new-shipment-type-${random}","isActive": "true","stores": ["AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] new_shipment_type_uuid
+ # Create new shipment type with existing name
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "not_unique_name","key": "second-shipment-type-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] shipment-types
+ And Save value to a variable: [data][id] shipment_type_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] not_unique_name
+ And Response body parameter should be: [data][attributes][key] second-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link for created entity: ${shipment_type_id}
+ # check that first shipment time still exist and not overrided
+ And I send a GET request: /shipment-types/
+ And I send a GET request: /shipment-types/${new_shipment_type_uuid}
+ And Response body parameter should be: [data][attributes][key] new-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][name] not_unique_name
+ [Teardown] Run Keywords Delete shipment type in DB: new-shipment-type-${random}
+ ... AND Delete shipment type in DB: second-shipment-type-${random}
+
+Update_sipment_type_change_name_store_relation_and_deactivate
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "name${random}","key": "update-shipment-type-key${random}","isActive": "true","stores": ["DE"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] shipment_type_uuid
+ # Update the Delivery Type with new attributes via PATCH request
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ And Response body parameter should be: [data][attributes][name] updated_name${random}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][stores] AT
+ And Response body has correct self link internal
+ [Teardown] Delete shipment type in DB: update-shipment-type-key${random}
+
+Retrive_single_shipment_type_with_valid_token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type${random}","key": "shipment-key${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] delivery_type_uuid
+ When I send a GET request: /shipment-types/${delivery_type_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] shipment-types
+ And Response body parameter should be: [data][attributes][name] shipment-type${random}
+ And Response body parameter should be: [data][attributes][key] shipment-key${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link internal
+ [Teardown] Delete shipment type in DB: shipment-key${random}
+
+Retrive_list_of_shipment_types_with_valid_token_and_pagination
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "shipment-key1${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "shipment-key2${random}","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?page[offset]=0&page[limit]=2
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array in response should contain property with NOT EMPTY value: [data] id
+ And Each array element of array in response should contain property with value: [data] type shipment-types
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][key]
+ And Each array element of array in response should contain property with value in: [data] [attributes][isActive] True False
+ And Response should contain the array larger than a certain size: [data][0][attributes][stores] 0
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of the array in response should contain a nested array larger than a certain size: [data] [attributes][stores] 0
+ [Teardown] Run Keywords Delete shipment type in DB: shipment-key1${random}
+ ... AND Delete shipment type in DB: shipment-key2${random}
+
+Retrive_list_of_shipment_types_with_filtering
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "shipment-key1${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "shipment-key2${random}","isActive": "true","stores": ["AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type3${random}","key": "shipment-key3${random}","isActive": "true","stores": ["DE"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?filter[shipment-types.stores]=AT
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array in response should contain property with value NOT in: [data] [attributes][key] shipment-key3${random}
+ [Teardown] Run Keywords Delete shipment type in DB: shipment-key1${random}
+ ... AND Delete shipment type in DB: shipment-key2${random}
+ ... AND Delete shipment type in DB: shipment-key3${random}
+
+Retrive_list_of_shipment_types_with_sorting_by_key_ASC
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "aaa_shipment-key1","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "www_shipment-key2","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?sort=key
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][attributes][key] aaa_shipment-key1
+ And Response body has correct self link
+ [Teardown] Run Keywords Delete shipment type in DB: aaa_shipment-key1
+ ... AND Delete shipment type in DB: www_shipment-key2
+
+
+Retrive_list_of_shipment_types_with_sorting_by_key_DESC
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "aaa_shipment-key1","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "www_shipment-key2","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?sort=-key
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][attributes][key] www_shipment-key2
+ And Response body has correct self link
+ [Teardown] Run Keywords Delete shipment type in DB: aaa_shipment-key1
+ ... AND Delete shipment type in DB: www_shipment-key2
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/negative.robot
new file mode 100644
index 0000000..b2b154b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/negative.robot
@@ -0,0 +1,38 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+New_warehouse_token_without_autorization
+ [Tags] skip-due-to-issue
+ [Documentation] https://spryker.atlassian.net/browse/FRW-2142
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Autorization is required.
+
+New_warehouse_token_with_invalid_token
+ [Tags] skip-due-to-issue
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1728
+ When I set Headers: Authorization=fake_token Content-Type=application/x-www-form-urlencoded
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+New_warehouse_token_for_admin_user_who_is_not_a_WH_user
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${admin_not_warehouse_user.email}","password": "${admin_not_warehouse_user.password}"}
+ Then Response status code should be: 200
+ And Save value to a variable: [access_token] bapi_token
+ When I set Headers: Authorization=Bearer ${bapi_token}
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [0][code] 5101
+ And Response body parameter should be: [0][message] Operation is forbidden.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/positive.robot
new file mode 100644
index 0000000..59ea6a8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_tokens/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi
+
+*** Test Cases ***
+Generate_new_user_token
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+# Generate_new_warehouse_token
+# # needs to be completed as werahouse token can be created only for user who is a warehouse user with assigned and ACTIVE warehouse.
+# # Making user a warehouse user is available now only via Back office frontend.
+# When I set Headers: Content-Type=application/x-www-form-urlencoded
+# When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+# Then Response status code should be: 200
+# And Save value to a variable: [access_token] bapi_token
+# When I set Headers: Authorization=${bapi_token} Content-Type=application/x-www-form-urlencoded
+# And I send a POST request: /warehouse-tokens {}
+# Then Response status code should be: 201
+# And Response body parameter should be: [data][type] warehouse-tokens
+# And Response body parameter should be: [data][attributes] Bearer
+# And Response body parameter should be greater than: [data][attributes][expiresin] 0
+# And Response body parameter should be less than: [data][attributes][expiresin] 30000
+# And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+# And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+# And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+# And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/negative.robot
new file mode 100644
index 0000000..017b63c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/negative.robot
@@ -0,0 +1,203 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+*** Test Cases ***
+Create_warehouse_user_assignment_with_invalid_token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 401
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Create_warehouse_user_assignment_without_token
+ And I set Headers: Content-Type=${default_header_content_type}
+ Then Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Create_warehouse_user_assignment_with_invalid_body
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "test","warehouse" :{"uuid": "${warehouse_user[0].admin_user_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Create_warehouse_user_assignment_with_empty_body
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1597
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {}}
+ Then Response status code should be: 400
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Create_warehouse_user_assignment_with_incorrect_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "invalid", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Create_warehouse_user_assignment_with_duplicate_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5206
+ And Response should return error message: Warehouse user assignment already exists.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Get_warehouse_user_assignments_by_UUID_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Get_user_assignments_by_UUID_with_invalid_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ And I get access token by user credentials: invalid
+ Then I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Get_user_assignments_by_invalid_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ Then I send a GET request: /warehouse-user-assignments/invalid
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Get_user_assignments_list_with_invalid_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Get_user_assignments_list_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 403
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Update_warehouse_user_assignment_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Update_warehouse_user_assignment_with_invalid_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Update_warehouse_user_assignment_without_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Then I send a PATCH request: /warehouse-user-assignments/invalid {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Delete_warehouse_user_assignment_without_token
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5850
+ [Tags] skip-due-to-issue
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 400
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+ Delete_warehouse_user_assignment_with_invalid_token
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ When Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].admin_user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].admin_user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/positive.robot
new file mode 100644
index 0000000..0756790
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/bapi/warehouse_user_assignments/positive.robot
@@ -0,0 +1,270 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi
+
+*** Test Cases ***
+Assign_user_to_warehouse
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response reason should be: Created
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link for created entity: ${warehouse_assignment_id}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Assign_user_to_warehouse_with_include
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response body parameter should not be EMPTY: [data][relationships][users][data][0][id]
+ And Each array in response should contain property with NOT EMPTY value: [data][relationships][users][data] id
+ And Each array element of array in response should contain property with value: [data][relationships][users][data] type users
+ And Each array in response should contain property with NOT EMPTY value: [included] id
+ And Each array element of array in response should contain property with value: [included] type users
+ And Response body parameter should be: [included][0][attributes][username] ${warehouse_user[0].admin_user_name}
+ And Response body parameter should be: [included][0][attributes][firstName] ${warehouse_user[0].admin_user_first_name}
+ And Response body parameter should be: [included][0][attributes][lastName] ${warehouse_user[0].admin_user_last_name}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Get_warehouse_user_assignments_by_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+Get_warehouse_user_assignments_list
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ # assign several warehouses to one user [only one warehouse active]
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should be in: [data][0][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be in: [data][1][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][1][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].admin_user_uuid}
+ And Response body parameter should be: [data][1][attributes][userUuid] ${warehouse_user[0].admin_user_uuid}
+ And Response body parameter should be in: [data][0][attributes][isActive] False True
+ And Response body parameter should be in: [data][1][attributes][isActive] False True
+ And Response body parameter should be in: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name} ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be in: [data][1][attributes][warehouse][name] ${warehouse[0].warehouse_name} ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ And Response body parameter should be: [data][1][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_assignment_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 1
+ # assign several users to one warehouse
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.uuid]=${warehouse_assignment_id_1}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.warehouseUuid]=${warehouse[0].video_king_warehouse_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].de_admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_user_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.userUuid]=${warehouse_user[0].admin_user_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_isActive
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.isActive]=true
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].de_admin_user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+
+Update_warehouse_user_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"false"}}}
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+ Create_warehouse_user_assignment_with_multiple_active_assignments
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] True
+ # when we creating second active user warehouse assignment for one user,the existing one assignment deactivated
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+
+
+Update_one_of_already exist_warehouse_user_assignment_with_two_assignments_to active
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id_1} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/dynamic_store/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/dynamic_store/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..bce095d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/dynamic_store/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,27 @@
+# *** Settings ***
+# Resource ../../../../../../resources/common/common_api.robot
+# Suite Setup API_suite_setup
+# Test Setup API_test_setup
+# Test Tags glue
+
+
+# *** Test Cases ***
+# ENABLER
+# API_test_setup
+
+
+# # SEARCH PARAMETERS #
+
+
+# Search_by_abstract_sku_per_store
+# [Tags] dms-on
+# When I set Headers: store=DE
+# Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+# And Response status code should be: 200
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] ${abstract_available_product_with_stock.price_de}
+# When I set Headers: store=AT
+# Then I send a GET request: /catalog-search?q=${abstract_available_product_with_stock.sku}
+# And Response status code should be: 200
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+# And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] ${abstract_available_product_with_stock.price_at}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
new file mode 100644
index 0000000..f4be9c9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Get_alternative_abstract_with_nonexistant_SKU
+ When I send a GET request: /concrete-products/fake/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_with_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_without_SKU
+ When I send a GET request: /concrete-products//abstract-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
new file mode 100644
index 0000000..90bfd79
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
@@ -0,0 +1,53 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Product_has_abstract_alternative
+ [Documentation] https://spryker.atlassian.net/browse/CC-16998
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-alternative-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body parameter should have datatype: [data][0][attributes][name] str
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_product_with_alternative.sku}
+ And Response body has correct self link
+
+
+Product_has_abstract_alternative_with_includes
+ [Documentation] https://spryker.atlassian.net/browse/CC-16998
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}/abstract-alternative-products?include=abstract-product-image-sets,abstract-product-availabilities,abstract-product-prices,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body has correct self link
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: abstract-product-prices
+
+Product_has_no_abstract_alternative
+ When I send a GET request: /concrete-products/${product_with_relations.has_upselling_products.concrete_sku}/abstract-alternative-products
+ Then Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ And Response reason should be: OK
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
new file mode 100644
index 0000000..213acf9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product inventory-management marketplace-inventory-management
+
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_abstract_availability_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
new file mode 100644
index 0000000..0874a5c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
@@ -0,0 +1,65 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product inventory-management marketplace-inventory-management
+
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Product_is_available_with_stock_and_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock2}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock2}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0.0000000000
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_with_stock
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+
+Product_is_available_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+# No demo data for B2C BUG CC-18820
+Product_is_unavailable
+ When I send a GET request: /abstract-products/${product_availability.abstract_unavailable_product}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_unavailable_product}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_10}
+ And Response body has correct self link
+
+Product_is_available_with_3_concrete_stocks_combined
+ #checks that stock of all 3 concretes as aggregated in response
+ When I send a GET request: /abstract-products/${abstract_available_product_with.concretes_3_sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
new file mode 100644
index 0000000..00ecd5c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_image_sets_by_concrete_sku
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_by_not_existing_sku
+ When I send a GET request: /abstract-products/test/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_with_missing_sku_in_url
+ When I send a GET request: /abstract-products//abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
new file mode 100644
index 0000000..0432599
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Abstract_image_sets_with_one_concrete
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
+
+Abstract_image_sets_with_several_concretes
+ When I send a GET request: /abstract-products/${abstract_available_product_with.concretes_3_sku}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with.concretes_3_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
new file mode 100644
index 0000000..6e6030e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_prices_by_concrete_sku
+ When I send a GET request: /abstract-products/${concrete_product_with_abstract_product_alternative.sku}/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_by_non_existing_sku
+ When I send a GET request: /abstract-products/fake/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_with_missing_sku_in_url
+ When I send a GET request: /abstract-products//abstract-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
new file mode 100644
index 0000000..09f9504
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
@@ -0,0 +1,88 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_product_prices_detault_only
+ When I send a GET request: /abstract-products/${abstract_available_product_with.concretes_3_sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Get_abstract_product_volume_prices
+ When I send a GET request: /abstract-products/${concrete_product.product_with_volume_prices.abstract_sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_volume_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][grossAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][netAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][quantity] 1
+ And Response body has correct self link
+
+Get_abstract_product_original_prices
+ When I send a GET request: /abstract-products/${concrete_product.product_with_original_prices.abstract_sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than: [data][0][attributes][prices][1][grossAmount] ${default_price}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.code}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.name}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.symbol}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${array}
+ And Response body has correct self link
+
+Get_abstract_product_original_prices_CHF
+ When I send a GET request: /abstract-products/${concrete_product.product_with_original_prices.abstract_sku}/abstract-product-prices?currency=CHF&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.abstract_sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than: [data][0][attributes][prices][1][grossAmount] ${default_price}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.chf.code}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.chf.name}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.chf.symbol}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${array}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/negative.robot
new file mode 100644
index 0000000..4813a06
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_product_by_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_product_with_alternative.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_by_fake_SKU
+ When I send a GET request: /abstract-products/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_with_missing_SKU
+ When I send a GET request: /abstract-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/positive.robot
new file mode 100644
index 0000000..e6e285a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/abstract_product_endpoints/abstract_products/positive.robot
@@ -0,0 +1,156 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product tax product-labels product-options inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Abstract_product_with_one_concrete
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 1
+ And Response body parameter should contain: [data][attributes][superAttributesDefinition] ${abstract_available_product_with_stock.superAttributesDefinition}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_3_concrete
+ When I send a GET request: /abstract-products/${abstract_available_product_with.concretes_3_sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with.concretes_name_3}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 4
+ And Response body parameter should contain: [data][attributes][superAttributes] ${abstract_available_product_with.concretes_superattribute_3}
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_abstract_includes_for_availability_images_taxes_categories_and_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=abstract-product-availabilities,abstract-product-image-sets,product-tax-sets,category-nodes,abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][abstract-product-prices][data] 0
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: abstract-product-prices
+
+Abstract_product_with_abstract_includes_for_labels
+ [Setup] Trigger product labels update
+ When I send a GET request: /abstract-products/${abstract_product.product_with_label.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_label.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_label.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_label.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-labels][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+Abstract_product_with_abstract_includes_for_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_reviews.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_reviews.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_reviews.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-reviews][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-reviews
+ And Response include element has self link: product-reviews
+
+Abstract_product_with_abstract_includes_for_options
+ When I send a GET request: /abstract-products/${abstract_product.product_with_options.sku}?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_options.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_options.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_options.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-options][data] 0
+ And Response should contain the array larger than a certain size: [included] 1
+ And Response include should contain certain entity type: product-options
+ And Response include element has self link: product-options
+
+Abstract_product_with_3_concrete_and_concrete_nested_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${abstract_available_product_with.concretes_3_sku}?include=concrete-products,concrete-product-prices,concrete-product-image-sets,concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with.concretes_3_sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with.concretes_name_3}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 4
+ And Response should contain the array larger than a certain size: [included] 15
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include element has self link: concrete-products
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+
+Abstract_product_in_different_locales_languages
+ When I set Headers: Accept-Language=de-DE
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_de}
+ When I set Headers: Accept-Language=en-US
+ And I send a GET request: /abstract-products/${abstract_product.product_in_different_locales.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_in_different_locales.description_en}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/negative.robot
new file mode 100644
index 0000000..2bda11c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_acess_token_with_invalid_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":"fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_invalid_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"fake@spryker.com","password":"${yves_user.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_empty_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+
+Get_acess_token_with_empty_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: username => This value should not be blank.
+
+Get_acess_token_with_invalid_type
+ When I send a POST request: /access-tokens {"data":{"type":"access","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_acess_token_with_empty_type
+ When I send a POST request: /access-tokens {"data":{"type":"","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/positive.robot
new file mode 100644
index 0000000..b72f637
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/access_tokens/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_access_token_for_customer
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/negative.robot
new file mode 100644
index 0000000..cfb9cf5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/negative.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+#######POST#######
+Refresh_token_with_access_token
+ [Setup] I get access token for the customer: ${yves_user.email}
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_invalid_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "faketoken"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_empty_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": ""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: refreshToken => This value should not be blank.
+
+Refresh_token_with_invalid_type
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "access-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Refresh_token_with_deleted_refresh_token
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ ... AND I set Headers: Authorization=Bearer ${access_token}
+ ... AND I send a DELETE request: /refresh-tokens/${refresh_token}
+ ... AND Response status code should be: 204
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Failed to refresh token.
+
+#######DELETE#######
+# Spryker is designed so removing non-existent refresh token will return 204 for security reasons
+Delete_refresh_token_with_invalid_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /refresh-tokens/faketoken
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_refresh_token_with_missing_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_refresh_token_with_no_access_token
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Spryker is designed so that deleting will return 204, but the token will not be removed and can be used (done for security reasons)
+Delete_refresh_token_for_another_user
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Authorization=Bearer ${access_token}
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/positive.robot
new file mode 100644
index 0000000..a8ef4b1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/refresh_tokens/positive.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Refresh_access_token_for_customer
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Save value to a variable: [data][attributes][accessToken] refreshed_access_token
+ And Response body has correct self link internal
+ When I set Headers: Authorization=Bearer ${refreshed_access_token}
+ And I send a GET request: /customers
+ Then Response status code should be: 200
+
+Delete_refresh_token_for_customer
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I set Headers: Authorization=Bearer ${access_token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/negative.robot
new file mode 100644
index 0000000..7f5a506
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/negative.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer_with_invalid_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "invalid_grant_type","username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_missing_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_invalid_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "wrong_password"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_for_customer_with_invalid_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "fake@spryker.com","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","password": "${yves_user.password}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+
+Get_token_using_refresh_token_for_customer_with_missing_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "invalid_grant_type","refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_missing_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "invalid_refresh_token"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The refresh token is invalid.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/positive.robot
new file mode 100644
index 0000000..4487974
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/access_token_endpoints/token/positive.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer
+ I set Headers: Content-Type=${urlencoded_header_content_type}
+ I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ Response status code should be: 200
+ Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+
+Get_token_using_refresh_token_for_customer
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "${refresh_token}"}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/negative.robot
new file mode 100644
index 0000000..1771ab9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/negative.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_access_token_by_empty_email_and_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_with_blank_spaces
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username":" " ,"password":" "}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_valid_email_and_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_empty_email_and_valid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_wrong_email_format
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "abc","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_non_agent_email_and_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_invalid_email_and_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "spryker1232@gmail.com","password": "1234"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_invalid_email_and_valid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "spryker1232@gmail.com","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_vaild_email_and_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "4321"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_access_token_by_invalid_data_type
+ When I send a POST request: /agent-access-tokens {"data": {"type": "token","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/positive.robot
new file mode 100644
index 0000000..b9e09d1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_access_tokens/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_access_tokens
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] agent-access-tokens
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
new file mode 100644
index 0000000..adfa9b3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
@@ -0,0 +1,74 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_cannot_impersonate_customer_with_no_agent_token
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_wrong_token_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_invalid_token
+ [Setup] I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer fake
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+
+Agent_cannot_impersonate_customer_with_wrong_type
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-token","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Agent_cannot_impersonate_customer_with_invalid_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_empty_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_missing_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
new file mode 100644
index 0000000..eb12dfc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_customer_impersonation_token
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-customer-impersonation-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/negative.robot
new file mode 100755
index 0000000..3c01972
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/negative.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_searches_for_customers_with_no_token
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_searches_for_customers_with_customer_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/positive.robot
new file mode 100755
index 0000000..80b0865
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/agent_endpoints/agent_customer_search/positive.robot
@@ -0,0 +1,170 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist customer-account-management
+
+*** Test Cases ***
+Agent_can_get_search_for_customers_without_search_parameters
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 10
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${customer_reference.de_1}
+ And Response body parameter should be: [data][0][attributes][customers][9][customerReference] ${customer_reference.de_10}
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body has correct self link
+
+
+Agent_can_get_search_for_customers_by_first_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.first_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+
+Agent_can_get_search_for_customers_by_last_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.last_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+
+Agent_can_get_search_for_customers_by_email
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.email}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=so
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 2
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_substring_and_not_find_any
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=ghjk
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 0
+ And Response body has correct self link
+
+
+Agent_can_get_search_for_customers_with_larger_page_size
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=0&page[limit]=15
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 15
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${customer_reference.de_1}
+ And Response body parameter should be: [data][0][attributes][customers][14][customerReference] ${customer_reference.de_15}
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+ And Response body parameter should not be EMPTY: [links][self]
+
+
+Agent_can_get_search_for_customers_from_last_page
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=30&page[limit]=10
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][self]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/negative.robot
new file mode 100644
index 0000000..e528b88
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/negative.robot
@@ -0,0 +1,147 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_without_customerId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers//availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 4606
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=325tr
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Authorization=
+ ... AND I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+Subscribe_to_availability_notifications_with_empty_type
+ When I send a POST request: /availability-notifications {"data": {"type": "","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Subscribe_to_availability_notifications_without_type
+ When I send a POST request: /availability-notifications {"data": {"attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Subscribe_to_availability_notifications_with_invalid_sku
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "000","email": "${yves_user.email}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Each array element of array in response should contain property with value: [errors] code 4601
+ And Each array element of array in response should contain property with value: [errors] status ${404}
+ And Array in response should contain property with value: [errors] detail Product not found.
+
+Subscribe_to_availability_notifications_with_invalid_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "gmail"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail email => This value is not a valid email address.
+
+Subscribe_to_availability_notifications_with_empty_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "","email": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+
+Subscribe_to_availability_notifications_without_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+
+Subscribe_to_availability_notifications_with_existing_subscription
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4602
+ And Response should return error message: Subscription already exists.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_with_invalid_availability_notification_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/7fc6ebf
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4603
+ And Response should return error message: "Subscription doesnt exist."
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Delete_availability_notifications_without_availability_notification_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/positive.robot
new file mode 100644
index 0000000..3b8c6c5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/availability_notifications/positive.robot
@@ -0,0 +1,84 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_empty_list_of_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+#POST requests
+Subscribe_to_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Subscribe_to_availability_notifications_with_non_existing_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "test1234546@gmail.com"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] test1234546@gmail.com
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all availability notifications: ${yves_user.reference}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/${availability_notification_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/negative.robot
new file mode 100644
index 0000000..cb5ac00
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Retrieves_my_availability_notifications_with_missing_auth_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_my_availability_notifications_with_invalid_auth_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/positive.robot
new file mode 100644
index 0000000..5d3d453
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/availability_endpoints/my_availability_notifications/positive.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_my_availability_notifications
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${concrete_product_with_abstract_product_alternative.sku}","email": "${yves_user.email}"}}}
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][0][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${concrete_product_with_abstract_product_alternative.sku}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] localeName
+ And Each array element of array in response should contain nested property: [data] [attributes] email
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/negative.robot
new file mode 100644
index 0000000..8452eb6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_bundled_products_with_nonexisting_concrete_sku
+ [Documentation] there is a bug - https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/fake/bundled-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_bundled_products_with_invalid_concrete_sku
+ [Documentation] there is a bug - https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/:sku/bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_bundled_products_with_missing_concrete_sku
+ When I send a GET request: /concrete-products//bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/positive.robot
new file mode 100644
index 0000000..d7f0903
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/bundle_endpoints/bundled_products/positive.robot
@@ -0,0 +1,81 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_concrete_bundled_products_inside_concrete_bundle
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Response body parameter should be in: [data][0][attributes][sku] ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be in: [data][1][attributes][sku] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be in: [data][2][attributes][sku] ${bundle_product.concrete.product_4_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_3_sku}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][quantity] ${products_in_bundle.qty_of_each_product}
+ And Response body has correct self link
+
+Get_concrete_bundled_products_inside_concrete_bundle_with_included_concretes
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/bundled-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property with value: [data] [relationships][concrete-products][data][0][type] concrete-products
+ And Response should contain the array of a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+
+Get_concrete_bundle_product_with_bundled_products_include
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract.product_1_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] ${products_in_bundle.total_qty_of_products}
+ And Each array element of array in response should contain property with value: [data][relationships][bundled-products][data] type bundled-products
+ And Response should contain the array larger than a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_abstract_bundle_product_with_bundled_products_include
+ When I send a GET request: /abstract-products/${bundle_product.abstract.product_1_sku}?include=bundled-products,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${bundle_product.abstract.product_1_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.abstract.product_1_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.product_name}
+ And Response body parameter should be: [data][attributes][attributeMap][product_concrete_ids] ${bundle_product.concrete.product_1_sku}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 1
+ And Response body parameter should be: [data][relationships][concrete-products][data][0][id] ${bundle_product.concrete.product_1_sku}
+ And Response should contain the array larger than a certain size: [included] ${products_in_bundle.total_qty_of_products}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_concrete_bundled_products_for_nonbundle_product
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/negative.robot
new file mode 100644
index 0000000..776bb8f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/negative.robot
@@ -0,0 +1,245 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core
+
+*** Test Cases ***
+Get_cart_by_cart_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_cart_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/12345678
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_cart_by_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Get_cart_by_customer_id_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Authorization=234567thgf
+ When I send a GET request: /customers/${Yves_second_user.reference}/carts
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_customer_id_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${Yves_second_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ When I send a GET request: /customers/user-01/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ When I send a GET request: /customers//carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${Yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Create_cart_with_invalid_access_token
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_when_cart_already_exists
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Customer already has a cart.
+
+#PATCH requests
+Update_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=wrong_tag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Update_cart_without_access_token
+ [Setup] I set Headers: Authorization= If-Match=wrong_tag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Update_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/8567km {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+
+Update_cart_without_cart_id
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=wrong_tag
+ When I send a PATCH request: /carts/ {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_cart_from_another_customer_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_cart_with_invalid_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=${token} If-Match="3278654tv3"
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+
+Update_cart_without_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 428
+ And Response reason should be: Precondition Required
+ And Response should return error message: If-Match header is missing.
+ And Response should return error code: 005
+
+Update_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "car","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Update_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Update_cart_with_invalid_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "DEK"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+
+
+Delete_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart could not be deleted.
+ And Response should return error code: 105
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/positive.robot
new file mode 100644
index 0000000..82147b4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/carts/positive.robot
@@ -0,0 +1,233 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax promotions-discounts marketplace-promotions-discounts spryker-core customer-access multiple-carts
+
+*** Test Cases ***
+#GET requests
+Get_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a GET request: /carts/${cart_id}
+ Then Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body has correct self link internal
+
+Get_cart_without_cart_id
+# Spryker is designed so that we can get all carts same as for /customers/{customerId}/carts request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a GET request: /carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][0][id] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+
+Get_cart_by_cart_id_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "1"}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Each array element of array in response should contain property: [data][relationships][items][data] id
+ And Each array element of array in response should contain property with value: [included] type items
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+
+Get_cart_by_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+
+Get_cart_with_included_cart_rules
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": 4}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] carts
+ And Response body parameter should be: [data][0][id] ${cart_id}
+ And Response body parameter should be: [data][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][0][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][0][attributes][discounts][0][displayName] 10% off minimum order
+ And Response body parameter should be: [data][0][attributes][discounts][0][amount] 3202
+ And Each array element of array in response should contain property with value: [data][0][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][0][relationships][cart-rules][data] id
+ And Response body parameter should be: [included][0][attributes][amount] 3202
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Get_cart_with_included_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "8"}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts?include=promotional-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] carts
+ And Response body parameter should be: [data][0][id] ${cart_id}
+ And Response body parameter should be: [data][0][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][0][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][0][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][0][attributes][discounts][0][displayName] 10% off minimum order
+ And Response body parameter should be: [data][0][attributes][discounts][0][amount] 6404
+ And Each array element of array in response should contain property with value: [data][0][relationships][promotional-items][data] type promotional-items
+ And Each array element of array in response should contain property: [data][0][relationships][promotional-items][data] id
+ And Each array element of array in response should contain property with value: [included] type promotional-items
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should be in: [included][0][attributes][sku] 112 068
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+
+#PATCH requests
+Update_cart_by_cart_id_with_all_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should contain: [data][attributes][totals] expenseTotal
+ And Response body parameter should contain: [data][attributes][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][totals] taxTotal
+ And Response body parameter should contain: [data][attributes][totals] subtotal
+ And Response body parameter should contain: [data][attributes][totals] grandTotal
+ And Response body parameter should contain: [data][attributes][totals] priceToPay
+ And Response body has correct self link internal
+ [Teardown] Run Keywords Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${ETag}
+ ... AND I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}"}}}
+ ... AND Response status code should be: 200
+Update_cart_with_empty_priceMod_currency_store
+# Spryker is designed so that we can send empty attributes: priceMod, currency, store and it will not be changed to the empty values.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Get ETag header value from cart
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should contain: [data][attributes][totals] expenseTotal
+ And Response body parameter should contain: [data][attributes][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][totals] taxTotal
+ And Response body parameter should contain: [data][attributes][totals] subtotal
+ And Response body parameter should contain: [data][attributes][totals] grandTotal
+ And Response body parameter should contain: [data][attributes][totals] priceToPay
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/negative.robot
new file mode 100644
index 0000000..fb1943a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/negative.robot
@@ -0,0 +1,91 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart spryker-core
+
+*** Test Cases ***
+Get_guest_cart_without_anonymous_customer_unique_id
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_empty_anonymous_customer_unique_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_non_existing_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a GET request: /guest-carts/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_wrong_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_empty_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Update_guest_cart_with_wrong_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/fake {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_without_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/ {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_guest_cart_with_invalid_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Update_guest_cart_without_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Update_guest_cart_update_price_mode_with_items_in_the_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.net}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 111
+ And Response body parameter should be: [errors][0][detail] Can’t switch price mode when there are items in the cart.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/positive.robot
new file mode 100644
index 0000000..cc5c0b2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/guest_carts/positive.robot
@@ -0,0 +1,197 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax spryker-core customer-access marketplace-promotions-discounts promotions-discounts
+
+*** Test Cases ***
+
+Create_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain value: [data] guest-carts
+ And Each array element of array in response should contain nested property with datatype: [data] id str
+ And Each array element of array in response should contain nested property with value: [data] [attributes][priceMode] ${mode.gross}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][currency] ${currency.eur.code}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][store] ${store.de}
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals][expenseTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals][discountTotal] int
+ And Each array element of array in response should be greater than: [data] [attributes][totals][taxTotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][subtotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][grandTotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_by_id
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_including_cart_items
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][relationships][guest-cart-items][data][0][type] guest-cart-items
+ And Response body parameter should be: [data][relationships][guest-cart-items][data][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Each array element of array in response should contain nested property with value: [included] type guest-cart-items
+ And Each array element of array in response should contain nested property with datatype: [included] id str
+ And Response should contain the array of a certain size: [included] 1
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+
+Retrieve_guest_cart_including_cart_rules
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Update_guest_cart_with_all_attributes
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Update_guest_cart_with_empty_priceMod_currency_store
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Convert_guest_cart_to_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Create a guest cart: ${random}-convert-guest-cart ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts?include=items
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+
+
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/negative.robot
new file mode 100755
index 0000000..351067a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/negative.robot
@@ -0,0 +1,315 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart product configurable-product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+###### POST #######
+Add_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+
+Add_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts//items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_item_to_cart_with_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=asdasfas
+ When I send a POST request: /carts/han/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "carts","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+
+###### PATCH #######
+Update_item_in_cart_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+
+Update_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/fake/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_cart_with_no_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts//items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_item_in_cart_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_with_invalid_parameters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+###### DELETE #######
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_id
+ When I send a DELETE request: /carts/${cart_id}/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts/fake/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_with_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts//items/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/positive.robot
new file mode 100755
index 0000000..a9eee46
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/cart_endpoints/items/positive.robot
@@ -0,0 +1,362 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart product marketplace-product-options product-options non-splittable-products configurable-product promotions-discounts marketplace-promotions-discounts inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+####POST#####
+Add_one_item_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+
+Add_two_items_to_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=items,concrete-products,abstract-products {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 2}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][2][type] items
+ And Response body parameter should be: [included][2][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 2
+ And Response body parameter should be: [included][2][attributes][groupKey] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][abstractSku] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][2][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][2][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Get_a_cart_with_included_items_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response body parameter should be: [included][1][type] items
+ And Response body parameter should be: [included][1][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 2
+ And Response body parameter should be: [included][1][attributes][groupKey] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][abstractSku] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][1][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][1][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Add_five_items_to_cart_with_included_cart_rules_and_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items?include=cart-rules,promotional-items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 5}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array larger than a certain size: [data][relationships][cart-rules][data] 0
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: items
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}
+ ... AND Response status code should be: 204
+#
+Add_product_with_options_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1,"merchantReference":"${merchant.sony_experts.merchant_id}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}
+ ... AND Response status code should be: 204
+Add_item_with_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 2}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] ${discount_concrete_product.product_1.total_sum_of_discounts}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_2.name}
+ And Response body parameter should be: [data][attributes][discounts][0][amount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be: [data][attributes][discounts][1][displayName] ${discount_1.name}
+ And Response body parameter should be: [data][attributes][discounts][1][amount] ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product.product_without_relations}
+ ... AND Response status code should be: 204
+
+Add_item_without_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}
+ ... AND Response status code should be: 204
+
+# ###### PATCH #######
+Change_item_qty_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 3}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be less than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Change_item_amount_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 3}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be less than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+Delete_item_form_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
+Add_a_configurable_product_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Update_configurable_product_quantity_in_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/negative.robot
new file mode 100644
index 0000000..08d98b0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_by_invalid_id
+ When I send a GET request: /category-nodes/test
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
+
+Get_category_node_by_non_exist_id
+ When I send a GET request: /category-nodes/111111
+ Then Response status code should be: 404
+ And Response should return error code: 703
+ And Response should return error message: "Cant find category node with the given id."
+
+Get_absent_category_node
+ When I send a GET request: /category-nodes
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/positive.robot
new file mode 100644
index 0000000..fee47fc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_nodes/positive.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_is_root_by_id
+ When I send a GET request: /category-nodes/${node_is_root_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${node_is_root_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][parents] 0
+ And Response should contain the array larger than a certain size: [data][attributes][children] 1
+ And Response body has correct self link internal
+
+Get_category_node_has_children_by_id
+ When I send a GET request: /category-nodes/${node_has_children_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${node_has_children_id}
+ And Response body parameter should be: [data][attributes][nodeId] ${node_has_children_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] nodeId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] name
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] order
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] children
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] parents
+ And Response body has correct self link internal
+
+Get_category_node_that_has_only_parents_by_id
+ When I send a GET request: /category-nodes/${node_has_only_parent_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${node_has_only_parent_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][children] 0
+ And Response should contain the array larger than a certain size: [data][attributes][parents] 0
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_trees/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_trees/positive.robot
new file mode 100644
index 0000000..2f9fb50
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/category_endpoints/category_trees/positive.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+#GET requests
+Get_category_trees
+ When I send a GET request: /category-trees
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type category-trees
+ And Each array element of array in response should contain property with value: [data] id ${None}
+ And Response body parameter should be: [data][0][type] category-trees
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] nodeId
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] order
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] url
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] children
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][name] ${category_nodes_storage_name}
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][url] ${category_nodes_storage_url}
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][1][children][0][nodeId]
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][1][children][0][order]
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][children][0][name] ${subcategory_nodes_storage_name}
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][1][children][0][url] ${subcategory_nodes_storage_url}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][1][children][0][children] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage] ${qty_of_categories_in_category_trees}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][1][children] ${qty_of_subcategories_in_category_trees}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/negative.robot
new file mode 100644
index 0000000..0844af1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/negative.robot
@@ -0,0 +1,421 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product spryker-core
+
+*** Test Cases ***
+# POST requests
+# bug CC-16699
+Create_order_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=faketoken Content-Type=${default_header_content_type}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_order_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+ And Response should return error code: 1105
+
+Create_order_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+
+Create_order_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "fake_email","salutation": "Freulein","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+
+Create_order_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Create_order_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Create_order_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Billing address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+
+
+Create_order_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shipments": [{"requestedDeliveryDate": "2021-09-29", "idShipmentMethod": 1, "items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"], "shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false}}],"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+
+Create_order_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_payment.method_name","paymentSelection": "fake_payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Checkout payment is not valid
+
+Create_order_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "","paymentMethodName": "","paymentSelection": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+
+Create_order_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+
+Create_order_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Shipment method not found.
+ And Response should return error code: 1102
+
+Create_order_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+
+Create_order_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": []}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1104
+ And Response should return error message: Cart is empty.
+
+Create_order_with_regular_shipment_&_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4301
+ And Response should return error message: Single and multiple shipments attributes are not allowed in the same request.
+
+Create_order_with_split_shipments_&_invalid_delivery_date
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "None"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": "None"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shipments.0.requestedDeliveryDate => This value is not a valid date.
+ And Array in response should contain property with value: [errors] detail shipments.1.requestedDeliveryDate => This value is not a valid date.
+
+Create_order_with_split_shipments_&_invalid_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_split_shipments_&_empty_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4302
+ And Response should return error message: Provided address is not valid. You can either provide address ID or address fields.
+
+Create_order_with_split_shipments_&_without_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: shipments.1.shippingAddress => This value should not be blank.
+
+
+Create_order_with_invalid_checkout_data
+ [Documentation] bug CC-16705 status code 201, but expected 422 with proper error
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["invalid"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1101
+ And Response should return error message: Checkout data is invalid.
+
+Create_order_with_invalid_payment_method
+ [Documentation] bug CC-16705 incorrect code in response
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${random}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1108
+ And Response should return error message: "Payment method “%s” of payment provider “%s” is invalid."
+
+Deleting_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a Delete request: /carts/${cart_id}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 105
+ And Response should return error message: Cart could not be deleted.
+
+Create_order_with_two_payment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${random}"},{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "Invoice"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1107
+ And Response should return error message: Multiple payments are not allowed.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/positive.robot
new file mode 100644
index 0000000..5478a21
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/checkout_endpoints/checkout/positive.robot
@@ -0,0 +1,536 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product payments inventory-management marketplace-inventory-management default-run-feature
+
+*** Test Cases ***
+#POST requests
+Create_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_include_orders
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 0
+
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_net_mode_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 15}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 5},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+
+Create_order_with_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_multiple_variants.variant1_sku}","quantity": 1}}}
+ ... AND Response body parameter should be: [data][type] carts
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${abstract_product.product_with_multiple_variants.variant1_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${abstract_product.product_with_multiple_variants.variant1_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${abstract_product.product_with_multiple_variants.variant1_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [included][0][attributes][shipments] 0
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 2
+
+Create_order_with_split_shipments_&_same_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${abstract_product.product_with_multiple_variants.variant1_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${abstract_product.product_with_multiple_variants.variant1_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${abstract_product.product_with_multiple_variants.variant1_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${abstract_product.product_with_multiple_variants.variant1_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+
+Create_order_with_same_items_in_different_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 1
+
+Create_order_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 3}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [included][0][attributes][totals][expenseTotal] ${discount_3.total_sum}
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 7800
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount_3.total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [included][0][attributes][items] 3
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultGrossPrice] ${discount_3.total_sum}
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_3.total_sum}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_3.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_3.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+Create_order_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_2.sku_1}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}", "${discount_concrete_product.product_2.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body has correct self link internal
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_1.total_sum_for_discounts_for_products_1_and_2} + ${discount_2.total_sum_for_discounts_for_products_1_2}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${discount_3.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ # #item 1 and item 2 - "20% off cameras and "10% off minimum order" discount
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][calculatedDiscounts] 2
+ And Response body parameter should be in: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name} ${discount_concrete_product.product_2.name_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} ${discount_concrete_product.product_2.sku_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name} ${discount_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description} ${discount_3.description}
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ #item 1 and item 2 - "20% off cameras and "10% off minimum order" discount
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name} ${discount_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description} ${discount_3.description}
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][1][quantity] 1
+ #item 1 and item 2 - "20% off cameras and "10% off minimum order" discount
+ And Response should contain the array of a certain size: [included][0][attributes][items][1][calculatedDiscounts] 2
+ And Response body parameter should be in: [included][0][attributes][items][1][name] ${discount_concrete_product.product_2.name_1} ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be in: [included][0][attributes][items][1][sku] ${discount_concrete_product.product_2.sku_1} ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name} ${discount_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description} ${discount_3.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][quantity] 1
+ #item 1 and item 2 - "20% off cameras and "10% off minimum order" discount
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][unitAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][sumAmount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_2.with_discount_20_percentage_off_storage_1} ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order_1} ${discount_concrete_product.product_2.with_discount_10_percentage_off_minimum_order_1}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name} ${discount_3.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description} ${discount_3.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][quantity] 1
+ # calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["10% off minimum order"][sumAmount] ${discount_1.total_sum_for_discounts_for_products_1_and_2}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["10% off minimum order"][displayName] ${discount_1.name}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["10% off minimum order"][description] ${discount_1.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 2
+ # calculatedDiscounts - "20% off storage" discount
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["20% off cameras"][unitAmount] None
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["20% off cameras"][sumAmount] ${discount_2.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["20% off cameras"][displayName] ${discount_2.name}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["20% off cameras"][description] ${discount_2.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 2
+ # calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["Free standard delivery"][unitAmount] None
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["Free standard delivery"][sumAmount] ${discount_3.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["Free standard delivery"][displayName] ${discount_3.name}
+ And Response body parameter should be: [included][0][attributes][calculatedDiscounts]["Free standard delivery"][description] ${discount_3.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+Create_order_with_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku_1}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_product.sku_1}"]}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ # #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_product.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_product.sku_1}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxRateAverageAggregation] 0.00
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesOrderItemConfiguration][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
new file mode 100644
index 0000000..5a92f88
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Request_concrete_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
new file mode 100644
index 0000000..1c1d10f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product discontinued-products alternative-products
+
+*** Test Cases ***
+Get_concrete_alternative_product_for_a_product_that_has_none
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_2_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response reason should be: OK
+
+Get_concrete_alternative_product
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response body should contain: id
+ And Response body parameter should not be EMPTY: [data][0][attributes][sku]
+ And Response body parameter should contain: [data][0][attributes] isDiscontinued
+ And Response body parameter should contain: [data][0][attributes] discontinuedNote
+ And Response body parameter should contain: [data][0][attributes] averageRating
+ And Response body parameter should contain: [data][0][attributes] reviewCount
+ And Response body parameter should not be EMPTY: [data][0][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should contain: [data][0][attributes] attributes
+ Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 3
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should contain: [data][0][attributes] attributeNames
+ And Response should contain the array of a certain size: [data][0][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][0][attributes][attributeNames] 6
+ And Response body has correct self link
+
+Get_concrete_alternative_product_with_include
+ When I send a GET request: /concrete-products/${concrete_product_with_concrete_product_alternative.sku}/concrete-alternative-products?include=concrete-product-image-sets,concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 3
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+ And Response include element has self link: concrete-product-prices
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
new file mode 100644
index 0000000..4ed8677
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_product_with_alternative.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
new file mode 100644
index 0000000..c6b1b3f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
@@ -0,0 +1,44 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_concrete_SKU_with_stock
+ When I send a GET request: /concrete-products/${concrete_available_product.with_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_available_product.with_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_with_stock_and_never_out_of_stock
+ When I send a GET request: /concrete-products/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] True
+ And Response body parameter should contain: [data][0][attributes] quantity
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_without_stock
+ [Documentation] https://spryker.atlassian.net/browse/CC-26178 Task has been created for missed demo data
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/${concrete_available_product.without_stock}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete_available_product.without_stock}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_5}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
new file mode 100644
index 0000000..c03dfd8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_image_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_2_sku}/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
+
+Request_product_image_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
new file mode 100644
index 0000000..62a42d0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
@@ -0,0 +1,33 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_product_with_one_image_set
+ When I send a GET request: /concrete-products/${concrete_product.product_one_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+
+Request_concrete_product_with_multiple_images
+ When I send a GET request: /concrete-products/${concrete_product.product_multiple_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_multiple_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 19
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/negative.robot
new file mode 100755
index 0000000..16cce65
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Request_product_concrete_with_product_doesn't_exist
+ When I send a GET request: /concrete-products/354656u7i8
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_2_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_empty_SKU
+ When I send a GET request: /concrete-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_concrete_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/positive.robot
new file mode 100755
index 0000000..1ef6372
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products/positive.robot
@@ -0,0 +1,94 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####GET####
+Get_concrete_product_information_by_sku
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+
+Get_concrete_product_with_included_image_sets
+ When I send a GET request: /concrete-products/${concrete_product.product_one_image_set.sku}?include=concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.product_one_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.product_one_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+
+Get_concrete_product_with_included_availabilities_and_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}?include=concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.product_with_original_prices.concrete_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-availabilities
+
+Get_concrete_product_with_included_abstract_product
+ When I send a GET request: /concrete-products/${concrete_product.product_multiple_image_set.sku}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.product_multiple_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.product_multiple_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+
+Get_concrete_product_with_included_product_labels
+ [Setup] Trigger product labels update
+ When I send a GET request: /concrete-products/${concrete_product_with_alternative.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/negative.robot
new file mode 100644
index 0000000..e6782fc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/negative.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_product_prices_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_2_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Get_product_prices_with_empty_SKU
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products//concrete-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_product_prices_with_special_characters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_product_prices_by_concrete_sku_product_doesn't_exist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-products/4567890/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+
+
+Request_URL_type_is_wrong
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /concrete-product/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/positive.robot
new file mode 100644
index 0000000..806e290
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/concrete_products_endpoints/concrete_products_prices/positive.robot
@@ -0,0 +1,58 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####GET####
+Get_concrete_product_with_only_default_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body has correct self link
+
+Get_concrete_product_with_default_and_original_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices][0][grossAmount]
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${array}
+ And Response body has correct self link
+
+Get_concrete_product_with_volume_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.product_with_volume_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_volume_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body has correct self link
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/negative.robot
new file mode 100644
index 0000000..db5fcba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_page_list_by_fake_id
+ When I send a GET request: /cms-pages/:cms
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
+Get_cms_page_list_by_wrond_id
+ When I send a GET request: /cms-pages/${abstract_list.product_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/positive.robot
new file mode 100644
index 0000000..9fd9e9f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/cms_pages/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/cms_steps.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_pages_list
+ When I send a GET request: /cms-pages
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_pages.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body array element should contain property with value at least once: [data] [attributes][name] ${cms_pages.first_cms_page.name}
+ And Response body array element should contain property with value at least once: [data] [attributes][url] ${cms_pages.first_cms_page.url_en}
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value: [data] [attributes][isSearchable] True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body has correct self link
+
+Get_specific_cms_page
+ [Setup] Run Keywords I send a GET request: /cms-pages
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] cms_page_id
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][isSearchable]
+ And Response body should contain: pageKey
+ And Response body should contain: validTo
+ And Response body has correct self link internal
+
+Get_specific_cms_with_includes
+ [Setup] Add content product abstract list to cms page in DB ${cms_pages.cms_page_with_product_lists.id} apl-watches
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_pages.cms_page_with_product_lists.id}?include=content-product-abstract-lists
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_pages.cms_page_with_product_lists.id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should be: [data][attributes][name] ${cms_pages.cms_page_with_product_lists.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][content-product-abstract-lists][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: content-product-abstract-lists
+ And Response include element has self link: content-product-abstract-lists
+ [Teardown] Run Keyword Delete latest cms page version by uuid from DB ${cms_pages.cms_page_with_product_lists.id}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/negative.robot
new file mode 100644
index 0000000..6f6a744
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner_without_id
+ When I send a GET request: /content-banners
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_banner_with_wrong_content_id_type
+ When I send a GET request: /content-banners/${abstract_list.product_id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 2203
+ And Response should return error message: Content type is invalid.
+
+Get_banner_with_invalid_content_id
+ When I send a GET request: /content-banners/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/positive.robot
new file mode 100644
index 0000000..b399c6c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_banners/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner
+ When I send a GET request: /content-banners/${banner.id_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${banner.id_1}
+ And Response body parameter should be: [data][type] content-banners
+ And Response body parameter should be: [data][attributes][title] ${banner.name_1}
+ And Response body parameter should not be EMPTY: [data][attributes][subtitle]
+ And Response body parameter should contain: [data][attributes][imageUrl] png
+ And Response body parameter should not be EMPTY: [data][attributes][clickUrl]
+ And Response body parameter should be: [data][attributes][altText] ${banner.name_1}
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot
new file mode 100644
index 0000000..bb65898
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product content-item
+
+*** Test Cases ***
+Get_abstract_product_list_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_products_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_with_no_id
+ When I send a GET request: /content-product-abstract-lists
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_missing_id
+ When I send a GET request: /content-product-abstract-lists//abstract-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_no_id
+ When I send a GET request: /content-product-abstract-lists/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot
new file mode 100644
index 0000000..b56a671
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/content_endpoints/content_product_abstract_lists/positive.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product content-item
+
+*** Test Cases ***
+Abstract_product_list
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+
+Abstract_product_list_abstract_products
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}/abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_list.size}
+ And Each array element of array in response should contain property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_list.product1_sku}
+ And Response body parameter should be: [data][0][attributes][name] ${abstract_list.product1_name}
+ And Response body parameter should be: [data][1][attributes][sku] ${abstract_list.product2_sku}
+ And Response body parameter should be: [data][1][attributes][name] ${abstract_list.product2_name}
+
+
+Abstract_product_list_with_include
+ When I send a GET request: /content-product-abstract-lists/${abstract_list.product_id}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_list.product_id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-products][data] ${abstract_list.size}
+ And Response should contain the array of a certain size: [included] ${abstract_list.size}
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/negative.robot
new file mode 100644
index 0000000..8d8831a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/negative.robot
@@ -0,0 +1,309 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+######POST#####
+Create_customer_address_with_missing_required_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address3": "${default.address3}"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail city => This field is missing.
+ And Array in response should contain property with value: [errors] detail iso2Code => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultShipping => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultBilling => This field is missing.
+
+Create_customer_address_with_empty_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","country": "","iso2Code": "","company":"","phone": "","isDefaultShipping": "","isDefaultBilling": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+
+# BUG bug_CC-15866
+Create_customer_address_with_invalid_salutation
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "Fake","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+
+Create_customer_address_with_customer_reference_not_matching_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_non_existing_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/DE--10000/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers//addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_type
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+######GET#####
+Get_non-existent_customer_address
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Get_other_customer_address_list
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_address_list_for_non-existent_customer
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/fake/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Get_address_list_with_no_token
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Get_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_other_customer_address_by_id_and_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+######PATCH#####
+Patch_customer_address_without_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Patch_customer_address_with_fake_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses/fake {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Patch_another_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_another_customer_address_by_id_using_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_second_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_no_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers//addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_wrong_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/DE--1/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_empty_required_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": null,"firstName": null,"lastName": null, "address1": null,"address2": null,"zipCode": null,"city": null,"iso2Code": null}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+# Bug CC-15866
+Patch_customer_address_with_invalid_salutation
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "Fake"}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation =\u003E The value you selected is not a valid choice.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+######DELETE#####
+Delete_customer_address_with_wrong_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Delete_customer_address_with_no_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/positive.robot
new file mode 100644
index 0000000..a25b531
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/addresses/positive.robot
@@ -0,0 +1,243 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+#####POST#####
+Create_customer_address_with_all_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_only_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] None
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] None
+ And Response body parameter should be: [data][attributes][phone] None
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_shipping_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": true,"isDefaultBilling": false}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_billing_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": true}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+#GET
+Get_empty_list_of_customer_addresses
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ Response should contain the array of a certain size: [data] 0
+
+Get_list_of_customer_addresses_with_1_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] address_uid
+ And Response body parameter should be: [data][0][type] addresses
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][0][attributes][city] ${default.city}
+ And Response body parameter should be: [data][0][attributes][country] ${default.country}
+ And Response body parameter should be: [data][0][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][0][attributes][company] ${default.company}
+ And Response body parameter should be: [data][0][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][0][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][0][attributes][isDefaultBilling] True
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_list_of_customer_addresses_with_2_addresses
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": true,"isDefaultBilling": true}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] first_address_uid
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Save value to a variable: [data][1][id] second_address_uid
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${second_address_uid}
+ ... AND Response status code should be: 204
+
+#DELETE
+Delete_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/addresses
+ ... AND Response status code should be: 200
+ ... AND Response should contain the array of a certain size: [data] 1
+ ... AND Save value to a variable: [data][0][id] address_uid
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+
+
+#PATCH
+Update_customer_address_several_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ ... AND Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${address_uid}
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${changed.address1}
+ And Response body parameter should be: [data][attributes][address2] ${changed.address2}
+ And Response body parameter should be: [data][attributes][address3] ${changed.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${changed.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/negative.robot
new file mode 100644
index 0000000..a1c3be3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/negative.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+Access_restricted_resource_as_not_authorized_customer
+ I send a GET request: /wishlists
+ Response status code should be: 403
+ And Response reason should be: Forbidden
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/positive.robot
new file mode 100644
index 0000000..9c46868
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_access/positive.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+Resources_list_which_customer_can_access
+ I send a GET request: /customer-access
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should contain: [data][0][type] customer-access
+ And Response should contain the array of a certain size: [data][0][attributes] [resourceTypes] 2
+ And Response body parameter should be: [data][0][attributes][resourceTypes][0] wishlists
+ And Response body parameter should be: [data][0][attributes][resourceTypes][1] wishlist-items
+ And Response body has correct self link
+
+Access_restricted_resource_as_authorized_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /wishlists
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/negative.robot
new file mode 100644
index 0000000..7e207b0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/negative.robot
@@ -0,0 +1,51 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+Test Setup API_test_setup
+
+*** Test Cases ***
+Customer_confirmation_with_wrong_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"39085d16b04b34265910c7ea2a35367ggh"}}}
+ Response status code should be: 422
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ And Response should return error code: 423
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":""}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_without_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_type
+ And I send a POST request: /customer-confirmation {"data":{"type":"","attributes":{"registrationKey":"607a17d1c673f461ca40002ea79fddc0"}}}
+ Response status code should be: 400
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_already_used_confirmation_key
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 423
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/positive.robot
new file mode 100644
index 0000000..0691051
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_confirmation/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.female}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}+${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}+${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot
new file mode 100755
index 0000000..dec4cac
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/negative.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_wrong_email_format
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"xyz"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_empty_email
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_incorrect_type
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot
new file mode 100755
index 0000000..6ffb6b0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_forgotten_password/positive.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_with_all_required_fields_and_valid_data
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/negative.robot
new file mode 100755
index 0000000..5b5c268
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/negative.robot
@@ -0,0 +1,136 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_not_equal_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field newPassword should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_data_type
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_current_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: newPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password_confirmation
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_non_autorizated_user
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_not_valid_user_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new_additional}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 408
+ And Response should return error message: Invalid password
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_short_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"test","confirmPassword":"test"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_long_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_customer_reference
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/ {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"1234567890123","confirmPassword":"1234567890123"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_mandatory_fields
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/test123 {"data":{"type":"customer-password","attributes":{"newPassword":"${yves_user.password}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_invalid_access_token
+ Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_value_not_matching_password_policy
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"change1234","confirmPassword":"change1234"}}}
+ Response status code should be: 422
+ Response should return error code: 901
+ And Response reason should be: Unprocessable Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/positive.robot
new file mode 100755
index 0000000..e5907a5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_password/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_eighth_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_eighth_user.password}","newPassword":"${yves_eighth_user.password_new}","confirmPassword":"${yves_eighth_user.password_new}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new_additional}"}}}
+ Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new}"}}}
+ And Response status code should be: 201
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/negative.robot
new file mode 100755
index 0000000..37a47ba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/negative.robot
@@ -0,0 +1,85 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_without_customer_id
+ I send a PATCH request: /customer-restore-password/ {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"fake","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_without_restorePasswordKey
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: restorePasswordKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_confirmation_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"${yves_user.password}","confirmPassword":""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_short_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"test","confirmPassword":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_long_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_not_equal_new_password_and_confirm_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 406
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_url
+ I send a PATCH request: /customer-restorepassword/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/positive.robot
new file mode 100755
index 0000000..0562231
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/customer_endpoints/customer_restore_password/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_ninth_user.first_name}","lastName":"${yves_ninth_user.last_name}","gender":"${gender.female}","salutation":"${yves_ninth_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_ninth_user.password}","confirmPassword":"${yves_ninth_user.password}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I send a POST request: /customer-forgotten-password {"data": {"type": "customer-forgotten-password","attributes": {"email":"${user_email}"}}}
+ ... AND Save the result of a SELECT DB query to a variable: select restore_password_key from spy_customer where customer_reference = '${user_reference_id}' restore_key
+ When I send a PATCH request: /customer-restore-password/${user_reference_id} {"data":{"type":"customer-restore-password","id":"${user_reference_id}","attributes":{"restorePasswordKey":"${restore_key}","password":"${yves_ninth_user.password_new}","confirmPassword":"${yves_ninth_user.password_new}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${user_email} ${yves_ninth_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/negative.robot
new file mode 100644
index 0000000..c0139fe
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/negative.robot
@@ -0,0 +1,331 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_voucher_code_to_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_voucher_code_to_guest_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_invalid_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_empty_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+
+Add_voucher_to_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+
+Add_invalid_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_empty_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_to_guest_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_to_guest_cart_with_invalid_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a POST request: /guest-carts/fake_guest_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+
+Add_voucher_code_to_cart_without_voucher_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_guest_user_cart_without_voucher_discount
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_from_another_customer_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_from_another_customer_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_empty_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+#DELETE requests
+Delete_voucher_code_from_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Delete_voucher_code_from_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_invalid_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+
+Delete_empty_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_voucher_from_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_invalid_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_empty_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_from_guest_user_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_cart_id
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ When I send a DELETE request: /guest-carts/fake_guest_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_another_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.sku_with_voucher_code}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_another_customer_guest_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/positive.robot
new file mode 100644
index 0000000..28bfc40
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/discount_endpoints/vouchers/positive.robot
@@ -0,0 +1,158 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.sku_with_voucher_code}","quantity": 1}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_4.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+
+Add_voucher_code_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_4.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_including_vouchers
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.sku_with_voucher_code}","quantity": 1}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /carts/${cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][relationships][vouchers][data] 1
+
+ #included
+ And Response include should contain certain entity type: vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount_4.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response include element has self link: vouchers
+
+
+Add_voucher_code_to_guest_user_cart_including_vouchers
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][relationships][vouchers][data] 1
+ #included
+ And Response include should contain certain entity type: vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${discount_4.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response include element has self link: vouchers
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+#DELETE requests
+Delete_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.sku_with_voucher_code}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 1970
+
+Delete_voucher_code_from_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${discount_concrete_product.sku_with_voucher_code} 1
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /guest-carts
+ And Response body parameter should be: [data][0][attributes][totals][discountTotal] 1970
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/negative.robot
new file mode 100644
index 0000000..8b5e88f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-labels
+
+*** Test Cases ***
+Get_product_label_with_invalid_label_id
+ When I send a GET request: /product-labels/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_with_nonexistend_label_id
+ When I send a GET request: /product-labels/3001
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_without_label_id
+ When I send a GET request: /product-labels
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1202
+ And Response should return error message: Product label id is missing.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/positive.robot
new file mode 100644
index 0000000..93a008b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_labels/positive.robot
@@ -0,0 +1,58 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue alternative-products product product-labels discontinued-products
+
+*** Test Cases ***
+Get_new_product_label_by_id
+ When I send a GET request: /product-labels/${label.new.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.new.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.new.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_sale_product_label_by_id
+ When I send a GET request: /product-labels/${label.sale.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.sale.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.sale.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_discontinued_product_label_by_id
+ When I send a GET request: /product-labels/${label.discontinued.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.discontinued.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.discontinued.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_alternatives_product_label_by_id
+ When I send a GET request: /product-labels/${label.alternatives.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label.alternatives.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label.alternatives.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/negative.robot
new file mode 100755
index 0000000..9048a76
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_an_attribute_with_non_existent_attribute_id
+ When I send a GET request: /product-management-attributes/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4201
+ And Response should return error message: Attribute not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/positive.robot
new file mode 100755
index 0000000..5b03a92
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_management_attributes/positive.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_all_product_management_attributes
+ When I send a GET request: /product-management-attributes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 50
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-management-attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes][key]
+ And Response body parameter should not be EMPTY: [data][0][attributes][inputType]
+ And Response body parameter should not be EMPTY: [data][0][attributes][allowInput]
+ And Response body parameter should be in: [data][0][attributes][allowInput] True False
+ And Response body parameter should be in: [data][0][attributes][isSuper] True False
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][value]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][localizedValues]
+ And Response body parameter should be in: [data][0][attributes][values][0][localizedValues][0][localeName] ${locale.DE.name} ${locale.EN.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][localizedValues][0][translation]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain property with value in: [data] [attributes][allowInput] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isSuper] True False
+ And Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] localeName ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][localizedKeys] translation
+ And Each array element of nested array should contain property with value NOT in: [data] [attributes][localizedKeys] translation None
+ And Each array element of array in response should contain nested property: [data] [attributes] values
+ And Each array element of array in response should contain nested property: [data] [attributes][values] value
+ And Each array element of array in response should contain nested property: [data] [attributes][values] localizedValues
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_product_management_attribute_by_id_superattribute
+ When I send a GET request: /product-management-attributes/${product_management_superattribute_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_superattribute_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_superattribute_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][localeName]
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][translation]
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management_attribute_free_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_attribute_free_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_attribute_free_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_non_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management_attribute_no_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management_attribute_no_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management_attribute_no_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/negative.robot
new file mode 100644
index 0000000..520758e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/negative.robot
@@ -0,0 +1,78 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_a_review_with_non_existent_review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Product review is not found.
+
+Get_a_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews/78
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Create_a_product_review_without_access_token
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Create_a_product_review_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_a_product_review_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-review","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_a_product_review_with_missing_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_a_product_review_with_empty_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": "","nickname": "","summary": "","description": ""}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail rating => This value should be greater than or equal to 1.
+ And Array in response should contain property with value: [errors] detail summary => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail nickname => This value should not be blank.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/positive.robot
new file mode 100644
index 0000000..98153dc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_reviews/positive.robot
@@ -0,0 +1,81 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+Resource ../../../../../../resources/common/common_api.robot
+
+
+*** Test Cases ***
+Get_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] type product-reviews
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] rating
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][rating] int
+ And Each array element of array in response should contain nested property: [data] [attributes] nickname
+ And Each array element of array in response should contain nested property: [data] [attributes] summary
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+Get_subset_of_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews?page[offset]=1&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][0][attributes][rating]
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Get_product_reviews_for_product_with_no_reviews
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_product_review_by_id
+ [Setup] Run Keywords I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ ... AND Save value to a variable: [data][0][id] review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/${review_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${review_id}
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][attributes][rating]
+ And Response body parameter should have datatype: [data][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Create_a_product_review
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_options.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 202
+ And Response reason should be: Accepted
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] review_id
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should be: [data][attributes][rating] ${review.default_rating}
+ And Response body parameter should be: [data][attributes][nickname] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][summary] ${review.title}
+ And Response body parameter should be: [data][attributes][description] ${review.text}
+ And Response body has correct self link for created entity: ${review_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/negative.robot
new file mode 100755
index 0000000..1ffc2be
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_a_tax_set_with_concrete_sku
+ When I send a GET request: /abstract-products/${concrete_available_product.sku}/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
+
+Get_a_tax_set_with_missing_sku
+ When I send a GET request: /abstract-products//product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_a_tax_set_with_non_existing_sku
+ When I send a GET request: /abstract-products/fake/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/positive.robot
new file mode 100755
index 0000000..c18ee03
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/product_tax_sets/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_product_tax sets
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-tax-sets
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response should contain the array larger than a certain size: [data][0][attributes][restTaxRates] 1
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain property: [data][0][attributes][restTaxRates] name
+ And Each array element of array in response should contain property: [data][0][attributes][restTaxRates] rate
+ And Each array element of array in response should contain property: [data][0][attributes][restTaxRates] country
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/negative.robot
new file mode 100644
index 0000000..8a3190b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Get_related_products_without_abstract_SKU
+ When I send a GET request: /abstract-products//related-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_related_products_for_nonexistent_SKU
+ When I send a GET request: /abstract-products/not_a_SKU/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_related_products_for_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_available_product.sku}/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/positive.robot
new file mode 100644
index 0000000..f9ee459
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/related_products/positive.robot
@@ -0,0 +1,83 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Product_has_related_products
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_related_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributes] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeNames] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Product_has_related_products_with_includes
+ [Setup] Run Keywords Trigger product labels update
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.sku}/related-products?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [data][8][relationships][product-labels][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+Product_has_no_related_products
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/negative.robot
new file mode 100644
index 0000000..5213523
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/negative.robot
@@ -0,0 +1,89 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+#Logged in customer's cart
+Get_upselling_products_with_missing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=invalid
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_upselling_products_without_access_token
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_upselling_products_using_cart_of_other_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+#Guest user cart
+Get_upselling_products_with_missing_guest_cart_id
+ When I send a GET request: /guest-carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_empty_anonymous_id
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Get_upselling_products_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/positive.robot
new file mode 100644
index 0000000..28e1593
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/general_product_endpoints/upselling_products/positive.robot
@@ -0,0 +1,282 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+#Logged in customer's cart
+#bug: https://spryker.atlassian.net/browse/CC-17008
+Get_upselling_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+Get_upselling_products_plus_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_cart_containing_multiple_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_cart_without_upselling_relations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_for_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+#Guest user cart
+#bug: https://spryker.atlassian.net/browse/CC-17012
+Get_upselling_products_for_guest_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Get_upselling_products_for_guest_cart_plus_includes
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: product-reviews
+ And Response include element has self link: category-nodes
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Get_upselling_products_for_guest_cart_containing_multiple_products
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 2
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Get_upselling_products_for_guest_cart_without_upselling_relations
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${concrete_product.product_without_relations} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/negative.robot
new file mode 100644
index 0000000..776cde0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/negative.robot
@@ -0,0 +1,239 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cart spryker-core product configurable-product product-bundles non-splittable-products proces
+
+*** Test Cases ***
+Add_an_item_to_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a POST request: /guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Add_an_item_to_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_an_item_to_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts/guestCartId/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_an_non_existing_item_to_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"non_existing_item","quantity":"1"}}}
+ Then Array in response should contain property with value: [errors] code 102
+ And Array in response should contain property with value: [errors] code 113
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail Product "non_existing_item" not found
+ And Array in response should contain property with value: [errors] detail Cart item could not be added.
+
+Add_an_item_to_the_guest_cart_without_sku_attribute_and_quantity_attribute
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_an_item_to_the_guest_cart_without_sku_and_quantity_values
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"","quantity":""}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+
+Update_an_item_quantity_at_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Update_an_item_quantity_at_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Update_an_item_quantity_at_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Update_quantity_of_a_non_existing_item_at_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/non_existing_item {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 103
+ And Response reason should be: Not Found
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Update_an_item_quantity_at_the_guest_cart_without_quantity_attribute
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer} {"data":{"type":"guest-cart-items","attributes":{}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+
+Update_an_item_quantity_at_the_guest_cart_with_empty_quantity_value
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer} {"data":{"type":"guest-cart-items","attributes":{"quantity":""}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+
+Update_an_item_quantity_at_the_guest_cart_with_non_numeric_quantity_value
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer} {"data":{"type":"guest-cart-items","attributes":{"quantity":"test"}}}
+ Then Response status code should be: ${422}
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type numeric.
+
+Remove_an_item_from_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a DELETE request: /guest-carts/guestCartId/guest-cart-items/itemId
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Remove_a_non_existing_item_from_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/non_existing_item
+ Then Response status code should be: 404
+ And Response should return error code: 103
+ And Response reason should be: Not Found
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Remove_an_item_from_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a DELETE request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Remove_an_item_from_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ I send a POST request: /guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/positive.robot
new file mode 100644
index 0000000..3765d4a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/guest_carts/guest_cart_items/positive.robot
@@ -0,0 +1,212 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cart spryker-core product configurable-product product-bundles non-splittable-products prices
+
+*** Test Cases ***
+Add_an_item_to_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Each array element of array in response should contain property: [data][attributes][discounts] displayName
+ And Each array element of array in response should contain property: [data][attributes][discounts] amount
+ And Each array element of array in response should contain property: [data][attributes][discounts] code
+ And Response body parameter should contain: [data][attributes] thresholds
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_an_item_to_the_guest_cart_with_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [included][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_an_item_to_the_guest_cart_with_concrete_products_and_abstract_products_includes
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=concrete-products,abstract-products {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include should contain certain entity type: guest-cart-items
+ And Response include element has self link: guest-cart-items
+ And Response include element has self link: abstract-products
+ And Response include element has self link: concrete-products
+
+Add_an_item_to_the_guest_cart_with_cart_rules_and_promotional_items_includes
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=cart-rules,promotional-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity": 10}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][cart-rules][data] 1
+ And Response should contain the array of a certain size: [data][relationships][promotional-items][data] 2
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: guest-cart-items
+ And Response include should contain certain entity type: promotional-items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: guest-cart-items
+ And Response include element has self link: promotional-items
+
+Add_an_item_to_the_guest_cart_with_bundle_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=bundle-items,bundled-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should be: [included][0][attributes][sku] ${bundle_product.concrete.product_2_sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${bundle_product.concrete.product_3_sku}
+ And Response body parameter should be: [included][2][attributes][sku] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [included][3][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 1
+ And Response body parameter should be: [included][3][attributes][groupKey] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be: [included][3][attributes][abstractSku] ${bundle_product.abstract.product_1_sku}
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: bundled-items
+ And Response include should contain certain entity type: bundle-items
+ And Response include element has self link: bundled-items
+ And Response include element has self link: bundle-items
+
+Update_an_item_quantity_at_the_guest_cart_with_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Each array element of array in response should contain property: [data][attributes][discounts] displayName
+ And Each array element of array in response should contain property: [data][attributes][discounts] amount
+ And Each array element of array in response should contain property: [data][attributes][discounts] code
+ And Response body parameter should contain: [data][attributes] thresholds
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [included][0][id] ${concrete_available_product.with_offer}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Remove_an_item_from_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Update_configurable_product_quantity_in_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_uid}?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-cart-items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /guest-carts/${guest_cart_id}?include=guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/negative.robot
new file mode 100644
index 0000000..9fdc91d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/negative.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+*** Test Cases ***
+Retrieves_merchant_addresses_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-addresses
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-addresses
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/positive.robot
new file mode 100644
index 0000000..b0991bc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_addresses/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+*** Test Cases ***
+Retrieves_merchant_addresses
+ When I send a GET request: /merchants/${merchant.sony_experts.merchant_id}/merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchant.sony_experts.merchant_id}
+ And Response body parameter should be: [data][0][type] merchant-addresses
+ And Response body parameter should be: [data][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [data][0][attributes][addresses][0][city] ${merchant.sony_experts.addresses.city_munchen}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-addresses
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address2
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] longitude
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Retrieves_merchant_with_include_merchant_addresses
+ When I send a GET request: /merchants/${merchant.sony_experts.merchant_id}?include=merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchant.sony_experts.merchant_id}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should have datatype: [data][relationships] dict
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-addresses]
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-addresses
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] longitude
+ And Response body parameter should be: [included][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [included][0][attributes][addresses][0][city] ${merchant.sony_experts.addresses.city_munchen}
+ And Response body parameter should be: [included][0][attributes][addresses][0][address1] ${merchant.sony_experts.addresses.address1}
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/negative.robot
new file mode 100644
index 0000000..b20b119
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-opening-hours
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-opening-hours
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/positive.robot
new file mode 100644
index 0000000..464af40
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchant_opening_hours/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours
+ When I send a GET request: /merchants/${merchant.sony_experts.merchant_id}/merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchant.sony_experts.merchant_id}
+ And Response body parameter should be: [data][0][type] merchant-opening-hours
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-opening-hours
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][weekdaySchedule] list
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][dateSchedule] list
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] noteGlossaryKey
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_merchant_with_include_merchant_opening_hours
+ When I send a GET request: /merchants/${merchant.sony_experts.merchant_id}?include=merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchant.sony_experts.merchant_id}
+ And Response should contain the array of a certain size: [included][0][attributes][weekdaySchedule] 8
+ And Response should contain the array of a certain size: [included][0][attributes][dateSchedule] 154
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-opening-hours]
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-opening-hours
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] noteGlossaryKey
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][day] MONDAY
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeFrom] 07:00:00.000000
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeTo] 13:00:00.000000
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][date] 2024-01-01
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][noteGlossaryKey] "New Years Day"
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/negative.robot
new file mode 100644
index 0000000..b0575e7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieves_merchant_with_non_existent_id
+ When I send a GET request: /merchants/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/positive.robot
new file mode 100644
index 0000000..aed5c13
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/merchant_endpoints/merchants/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieves_list_of_merchants
+ When I send a GET request: /merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchants
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantName
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonRole
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonFirstName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonLastName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] logoUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] publicEmail
+ And Each array element of array in response should contain nested property: [data] [attributes] publicPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] bannerUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] deliveryTime
+ And Each array element of array in response should contain nested property: [data] [attributes] faxNumber
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] terms
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] cancellationPolicy
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] imprint
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] dataPrivacy
+ And Each array element of array in response should contain nested property: [data] [attributes] categories
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_a_merchant_by_id
+ When I send a GET request: /merchants/${merchant.sony_experts.merchant_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][id] ${merchant.sony_experts.merchant_id}
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][attributes][merchantName] ${merchant.sony_experts.merchant_name}
+ And Response body parameter should be: [data][attributes][merchantUrl] ${merchant.sony_experts.merchant_url}
+ And Response body parameter should be: [data][attributes][contactPersonRole] ${merchant.sony_experts.contact_person_role}
+ And Response body parameter should be: [data][attributes][contactPersonTitle] ${merchant.sony_experts.contact_person_title}
+ And Response body parameter should be: [data][attributes][contactPersonFirstName] ${merchant.sony_experts.contact_person_first_name}
+ And Response body parameter should be: [data][attributes][contactPersonLastName] ${merchant.sony_experts.contact_person_last_name}
+ And Response body parameter should be: [data][attributes][contactPersonPhone] ${merchant.sony_experts.contact_person_phone}
+ And Response body parameter should be: [data][attributes][publicEmail] ${merchant.sony_experts.public_email}
+ And Response body parameter should be: [data][attributes][publicPhone] ${merchant.sony_experts.public_phone}
+ And Response body parameter should be: [data][attributes][description] ${merchant.sony_experts.description}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][logoUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][bannerUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][deliveryTime]
+ And Response body parameter should not be EMPTY: [data][attributes][faxNumber]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][terms]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][cancellationPolicy]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][imprint]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][dataPrivacy]
+ And Response body parameter should have datatype: [data][attributes][categories] list
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/negative.robot
new file mode 100644
index 0000000..e32d176
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/negative.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue navigation spryker-core
+
+*** Test Cases ***
+Get_navigations_by_non_exist_id
+ When I send a GET request: /navigations/testNonExistNavigations
+ Then Response status code should be: 404
+ And Response should return error code: 1601
+ And Response should return error message: Navigation not found.
+
+
+Get_absent_navigations
+ When I send a GET request: /navigations
+ Then Response status code should be: 400
+ And Response should return error code: 1602
+ And Response should return error message: Navigation id not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/positive.robot
new file mode 100644
index 0000000..6067c18
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/navigation_endpoints/navigations/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core navigation category-management merchant-category
+
+*** Test Cases ***
+To_retrieve_a_navigation_tree
+ When I send a GET request: /navigations/MAIN_NAVIGATION
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][isActive] bool
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] children
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][nodeType] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][title] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][children] list
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][nodeType]
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][title]
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] children
+ And Response body has correct self link internal
+
+Get_navigation_tree_using_valid_navigation_key_with_category_nodes_included
+ When I send a GET request: /navigations/MAIN_NAVIGATION?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Should Contain The Array Larger Than a Certain Size: [included] 0
+ And Response Should Contain The Array Larger Than a Certain Size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][category-nodes]
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] type
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each Array Element Of Array In Response Should Contain Property With Value: [included] type category-nodes
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes nodeId
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes name
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaTitle
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaKeywords
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaDescription
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes isActive
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes order
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes url
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes children
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes parents
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/negative.robot
new file mode 100644
index 0000000..5888c54
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/negative.robot
@@ -0,0 +1,94 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue order-management marketplace-order-management spryker-core customer-access
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_order_by_order_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_with_invalid_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/fake_order_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+
+Get_customer_orders_list_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_customer_orders_list_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_by_order_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1,"merchantReference":"${merchant.sony_experts.merchant_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_concrete_product_alternative.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+
+
+Get_customer_orders_list_with_invalid_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/yves_user.reference/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/positive.robot
new file mode 100644
index 0000000..b71de0b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/order_endpoints/orders/positive.robot
@@ -0,0 +1,270 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cart checkout order-management marketplace-order-management marketplace-product merchant product product-bundles marketplace-packaging-units measurement-units packaging-units non-splittable-products shipment marketplace-shipment configurable-bundle configurable-product gift-cards spryker-core customer-access
+
+*** Test Cases ***
+#GET requests
+Get_order_by_order_id
+
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1,"merchantReference":"${merchant_sony_experts_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_concrete_product_alternative.sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should not be EMPTY: [data][attributes][expenses][0][name]
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${payment.provider_name}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+
+Get_order_by_order_id_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1,"merchantReference":"${merchant_sony_experts_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${bundle_product.concrete.product_1_sku}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Each array element of array in response should contain property with value: [data][attributes][items] bundleItemIdentifier ${None}
+ And Each array element of array in response should contain property: [data][attributes][items] relatedBundleItemIdentifier
+ And Response body parameter should be: [data][attributes][items][0][name] ${bundle_product.concrete.product_2_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${bundle_product.concrete.product_2_sku}
+ And Response body parameter should be: [data][attributes][items][1][name] ${bundle_product.concrete.product_3_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${bundle_product.concrete.product_3_sku}
+ And Response body parameter should be: [data][attributes][items][2][name] ${bundle_product.concrete.product_4_name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${bundle_product.concrete.product_4_sku}
+ #bundleItems
+ And Response body parameter should be: [data][attributes][bundleItems][0][name] ${bundle_product.product_name}
+ And Response body parameter should be: [data][attributes][bundleItems][0][sku] ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumGrossPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRate] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][refundableAmount] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][canceledAmount] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRateAverageAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][orderReference] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][uuid] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][isReturnable] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][idShipment] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][bundleItemIdentifier] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [data][attributes][bundleItems][0][metadata][image]
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][calculatedDiscounts] 0
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][productOptions] 0
+ And Response body has correct self link internal
+
+Get_customer_orders_list_without_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1,"merchantReference":"${merchant_sony_experts_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_concrete_product_alternative.sku}"]}}}
+ When I send a GET request: /orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+
+Get_customer_orders_list_without_order_id_with_pagination
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1,"merchantReference":"${merchant_sony_experts_id}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_concrete_product_alternative.sku}"]}}}
+ When I send a GET request: /orders?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] orders
+ And Response body parameter should contain: [data][0] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
new file mode 100644
index 0000000..a591614
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+Get_product_offer_availabilities_without_offerId
+ When I send a GET request: /product-offers//product-offer-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_product_offer_availabilities_with_invalid_offerId
+ When I send a GET request: /product-offers/InvalidOfferId/product-offer-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer was not found.
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
new file mode 100644
index 0000000..2d5f499
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+
+Get_product_offer_availabilities
+ I send a GET request: /concrete-products/${merchant.spryker.concrete_product_with_offer_sku}/product-offers
+ AND Save value to a variable: [data][0][id] offerId
+ When I send a GET request: /product-offers/${offerId}/product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type product-offer-availabilities
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] isNeverOutOfStock
+ And Each array element of array in response should contain nested property: [data] [attributes] availability
+ And Each array element of array in response should contain nested property: [data] [attributes] quantity
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][isNeverOutOfStock] bool
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][availability] bool
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][quantity] str
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/negative.robot
new file mode 100644
index 0000000..369e002
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieve_prices_of_a_product_offer_without_offerId
+ When I send a GET request: /product-offers//product-offer-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_product_offer_prices_with_invalid_offerId
+ When I send a GET request: /product-offers/InvalidOfferId/product-offer-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/postive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/postive.robot
new file mode 100644
index 0000000..e2b97bd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offer_prices/postive.robot
@@ -0,0 +1,83 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_product_offer_without_volume_price
+ I send a GET request: /concrete-products/${concrete_of_alternative_product_with_relations_upselling.sku}/product-offers
+ AND Save value to a variable: [data][0][id] offerId
+ When I send a GET request: /product-offers/${offerId}/product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type product-offer-prices
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] price
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][price] int
+ And Response body parameter should be greater than: [data][0][attributes][price] 0
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] priceTypeName
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] netAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] grossAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] currency
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][code] ${currency.eur.code}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][name] ${currency.eur.name}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Get_product_offer_with_volume_price
+ I send a GET request: /concrete-products/${concrete_available_product.with_stock}/product-offers
+ AND Save value to a variable: [data][0][id] offerId
+ When I send a GET request: /product-offers/${offerId}/product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type product-offer-prices
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] price
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][price] int
+ And Response body parameter should be greater than: [data][0][attributes][price] 0
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] priceTypeName
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] netAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] grossAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] currency
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][code] ${currency.eur.code}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][name] ${currency.eur.name}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0][volumePrices][0] grossAmount
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0][volumePrices][0] netAmount
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0][volumePrices][0] quantity
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response body has correct self link
+
+
+Get_default&original_prices_of_a_product_offer
+ I send a GET request: /concrete-products/${concrete_available_product.with_stock}/product-offers
+ AND Save value to a variable: [data][0][id] offerId
+ When I send a GET request: /product-offers/${offerId}/product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type product-offer-prices
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] price
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][price] int
+ And Response body parameter should be greater than: [data][0][attributes][price] 0
+ And Each array element of array in response should contain a nested array of a certain size: [data] [attributes][prices] 2
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] priceTypeName
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] netAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] grossAmount
+ And Each array element of array in response should contain nested property: [data] [attributes][prices][0] currency
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][priceTypeName] DEFAULT
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][1][priceTypeName] ORIGINAL
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][code] ${currency.eur.code}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][name] ${currency.eur.name}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/negative.robot
new file mode 100644
index 0000000..2a31a87
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/negative.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product
+
+*** Test Cases ***
+Get_product_offers_without_product_offer_id
+ When I send a GET request: /product-offers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_concrete_product_offers
+ When I send a GET request: /concrete-products/123456789/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_product_offer_with_volume_prices_included_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_denied_product_offer
+ When I send a GET request: /product-offers/offer404?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_invalid_offer_id
+ When I send a GET request: /product-offers/test
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_empty_product_id
+ When I send a GET request: /concrete-products//product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 312
+ And Response reason should be: Bad Request
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/positive.robot
new file mode 100644
index 0000000..a8d60ed
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/product_offer_endpoints/product_offers/positive.robot
@@ -0,0 +1,189 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_concrete_product_without_offers
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_all_concrete_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /concrete-products/${concrete_product.product_with_volume_prices.concrete_sku}/product-offers?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${second_offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offers
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${merchant_sony_experts_id}
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should contain: [data][0][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 6
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+ And Response body has correct self link
+
+Get_all_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should contain: [data][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 3
+ And Response should contain the array of a certain size: [data][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+
+Get_product_offer_with_gross_eur
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_net_eur
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices&priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_gross_chf
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Get_product_offer_with_net_chf
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices&priceMode=${mode.net}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Retrieving_product_offer
+ When I send a GET request: /product-offers/${active_offer}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body has correct self link internal
+
+Retrieving_product_offer_including_product_offer_prices
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][product-offer-prices][data]
+ And Response include element has self link: product-offer-prices
+ And Each array element of array in response should contain nested property with value: [included] [attributes][price] ${active_offer_price}
+ And Each array element of array in response should contain nested property with value: [included] id ${active_offer}
+ And Each array element of array in response should contain nested property: [included] type product-offer-prices
+ And Response should contain the array larger than a certain size: [included] 0
+
+Retrieving_product_offer_including_product_offer_availabilities
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][product-offer-availabilities][data]
+ And Response include element has self link: product-offer-availabilities
+ And Each array element of array in response should contain nested property with value: [included] id ${active_offer}
+ And Each array element of array in response should contain nested property: [included] type product-offer-availabilities
+ And Each array element of array in response should contain property with value NOT in: [included] attributes None
+
+Retrieving_product_offer_including_merchants
+ When I send a GET request: /product-offers/${active_offer}?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][merchants][data]
+ And Response include element has self link: merchants
+ And Each array element of array in response should contain nested property: [included] type merchants
+ And Each array element of array in response should contain property with value NOT in: [included] type None
+ And Each array element of array in response should contain property with value NOT in: [included] attributes None
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/return_reasons/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/return_reasons/positive.robot
new file mode 100644
index 0000000..fda7a5c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/return_reasons/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue return-management marketplace-return-management
+
+*** Test Cases ***
+#GET requests
+Get_return_reason
+ When I send a GET request: /return-reasons
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type return-reasons
+ And Each array element of array in response should contain nested property: [data] [attributes] reason
+ And Response should contain the array of a certain size: [data] ${return_reasons_qty}
+ And Each array element of array in response should contain nested property with value: [data] [id] None
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/negative.robot
new file mode 100644
index 0000000..440b607
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/negative.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+ ####POST####
+Create_a_return_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_a_return_with_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_return_for_order_item_that_cannot_be_returned
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_second_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_available_product.sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_with_invalid_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_reason
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"920fc22f-3fb6-53ec-bc5e-c4d321115462","reason":""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+
+####GET####
+Get_lists_of_returns_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /returns
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+
+Get_lists_of_returns_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /returns
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+####GET####
+Get_return_by_Id_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+
+Get_return_by_Id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+Get_return_by_Id_with_Invalid_return_reference
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find return by the given return reference."
+ And Response should return error code: 3602
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/positive.robot
new file mode 100644
index 0000000..4b38a06
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/returns_endpoints/returns/positive.robot
@@ -0,0 +1,208 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+###POST####
+Create_a_return
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason}"}]}}}
+ Then Save value to a variable: [data][id] returnId
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link for created entity: ${returnId}
+
+Create_a_return_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should not be empty: [included][0][attributes][uuid]
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason}
+ And Response body parameter should contain: [included][0][attributes] orderItemUuid
+
+####GET####
+Get_lists_of_returns
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ When I send a GET request: /returns
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+
+
+#
+Get_lists_of_returns_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${cart_id}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ When I send a GET request: /returns?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships] return-items
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] type
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] id
+ And Each array element of array in response should contain nested property with value: [data] [relationships][return-items][data][0][type] return-items
+ And Response include element has self link: return-items
+ And Response include should contain certain entity type: return-items
+ And Response body has correct self link
+ ####GET####
+Get_return_by_Id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnReference}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link internal
+
+
+Get_return_by_Id_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"GROSS_MODE","currency":"EUR","store":"DE"}}}
+ ... AND I send a GET request: /customers/${yves_user.reference}/carts
+ ... AND Save value to a variable: [data][0][id] CartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity":"1"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"DE","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [included][0][attributes][orderItemUuid] orderItemUuid
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnReference}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason}
+ And Response body parameter should be: [included][0][attributes][orderItemUuid] ${orderItemUuid}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/negative.robot
new file mode 100644
index 0000000..d785be0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/negative.robot
@@ -0,0 +1,45 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog
+
+*** Test Cases ***
+Search_without_query_parameter
+ When I send a GET request: /catalog-search?
+ Then Response status code should be: 200
+
+Search_with_invalid_currency
+ When I send a GET request: /catalog-search?q=¤cy=InvalidCurrency
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 313
+ And Response should return error message: Currency is invalid.
+
+Search_with_invalid_price_mode
+ When I send a GET request: /catalog-search?q=&priceMode=InvalidPriceMode
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 314
+ And Response should return error message: Price mode is invalid.
+
+Search_with_invalid_rating_min
+ When I send a GET request: /catalog-search?q=&rating[min]=InvalidMinRating5
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 503
+ And Response should return error message: Value of rating.min must be of type integer.
+
+Search_with_invalid_rating_max
+ When I send a GET request: /catalog-search?q=&rating[max]=InvalidMinRating5
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 503
+ And Response should return error message: Value of rating.max must be of type integer.
+
+Search_with_invalid_category
+ When I send a GET request: /catalog-search?q=&category=!@!@!
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 503
+ And Response should return error message: Value of category must be of type integer.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..0ad8c28
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,696 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product
+
+*** Test Cases ***
+##### SEARCH PARAMETERS #####
+Search_with_empty_search_criteria_all_default_values_check
+ When I send a GET request: /catalog-search?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ #Sorting
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamNames] ${sorting_options_qty}
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamLocalizedNames] ${sorting_options_qty}
+ And Response body parameter should contain: [data][0][attributes] currentSortParam
+ And Response body parameter should contain: [data][0][attributes] currentSortOrder
+ #Pagination
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][config][parameterName] page
+ And Response body parameter should be: [data][0][attributes][pagination][config][itemsPerPageParameterName] ipp
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][pagination][config][validItemsPerPageOptions] 3
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.middle}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.biggest}
+ #Abstract products
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] prices
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.eur.name}
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] images
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] grossAmount 1
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ #Filters - category
+ And Response body parameter should contain: [data][0][attributes] valueFacets
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][name] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][localizedName] Categories
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] ${default_qty.categories}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][parameterName] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][isMultiValued] False
+ #Filters - labels
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][name] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][localizedName] Label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][docCount] None
+ And Response should contain the array larger or equal than a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][parameterName] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][isMultiValued] True
+ #Filters - color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][name] color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][localizedName] Color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] ${default_qty.colors}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][parameterName] color
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][isMultiValued] True
+ #Filters - storage capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][name] storage_capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][localizedName] Storage Capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] ${default_qty.storage_capacity}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][config][parameterName] storage_capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][config][isMultiValued] True
+ #Filters - brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][name] brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][localizedName] Brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] ${default_qty.brands}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][config][parameterName] brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][config][isMultiValued] False
+ #Filters - touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][name] touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][localizedName] Touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] ${default_qty.touchscreen}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][config][parameterName] touchscreen
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][config][isMultiValued] False
+ #Filters - weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][name] weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][localizedName] Weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][6][values] ${default_qty.weight}
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][config][parameterName] weight
+ And Response body parameter should be: [data][0][attributes][valueFacets][6][config][isMultiValued] True
+ #Filters - Merchant
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][name] merchant_name
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][localizedName] Merchant
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][docCount] None
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][7][values] ${default_qty.merchant}
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][config][parameterName] merchant_name
+ And Response body parameter should be: [data][0][attributes][valueFacets][7][config][isMultiValued] True
+ #Filters - price
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][name] price-DEFAULT-EUR-GROSS_MODE
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][localizedName] Price
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][min] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][max] ${default_price.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_price.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][docCount] None
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][parameterName] price
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][isMultiValued] False
+ #Filters - rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][name] rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][localizedName] Ratings
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][docCount] None
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][min] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][max] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][config][parameterName] rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][config][isMultiValued] False
+ #Filters - category tree
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${tree_branches_qty}
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] nodeId
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] name
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] docCount
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] children
+ #Selflinks
+ And Response body has correct self link
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_by_attribute_that_does_not_return_products
+ When I send a GET request: /catalog-search?q=fakeProduct
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response body has correct self link
+
+Search_by_abstract_sku
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 3
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] prices
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] grossAmount 10
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+Search_by_full_name
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 11
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ And Response body has correct self link
+
+Search_by_concrete_sku
+ When I send a GET request: /catalog-search?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ And Response body has correct self link
+
+Search_by_name_substring
+ When I send a GET request: /catalog-search?q=Lenovo
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 11
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 11
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_product_with_alternative.name}
+ And Response body has correct self link
+
+Search_by_attribute_(brand)
+ When I send a GET request: /catalog-search?q=${brand_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 42
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 4
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][abstractProducts][0][abstractName] ${brand_4}
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 1
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][values][0][value] ${brand_4}
+ And Response body has correct self link
+
+Search_by_several_attributes
+ When I send a GET request: /catalog-search?q=${color_3}+${aspect_ratio}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 60
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 5
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+
+##### FILTERING #####
+Filter_by_rating_only_min
+ When I send a GET request: /catalog-search?q=&rating[min]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 6
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 6
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.max}
+
+Filter_by_rating_only_max
+ When I send a GET request: /catalog-search?q=rating[max]=${default_rating.min}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 19
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 2
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] ${default_rating.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] ${default_rating.min}
+
+Filter_by_rating_Min_max
+ When I send a GET request: /catalog-search?q=&rating[min]=3&rating[max]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] 3
+
+Filter_by_price_only_min
+ When I send a GET request: /catalog-search?q=&price[min]=1000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 3
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 100000
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_price.max}
+
+Filter_by_price_only_max
+ When I send a GET request: /catalog-search?q=&price[max]=3000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 209
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 18
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_price.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 300000
+
+Filter_by_price_Min_max
+ When I send a GET request: /catalog-search?q=&price[min]=1000&price[max]=3000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] 100000
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] 300000
+
+Filter_by_brand_one_brand
+ When I send a GET request: /catalog-search?q=&brand=${brand_4}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 42
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${brand_4}
+ And Response body has correct self link
+Filter_by_brand_two_brands
+ When I send a GET request: /catalog-search?q=&brand[]=${brand_4}&brand[]=${brand_5}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 53
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 5
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][0] ${brand_4}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue][1] ${brand_5}
+Filter_by_brand_empty_brand
+ When I send a GET request: /catalog-search?q=&brand=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${EMPTY}
+ And Response body has correct self link
+Filter_by_brand_non_existing_brand
+ When I send a GET request: /catalog-search?q=&brand=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] test123
+ And Response body has correct self link
+
+Filter_by_label_one_label
+ When I send a GET request: /catalog-search?q=&label=${label.new.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 5
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 5
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] ${label.new.name}
+ And Response body has correct self link
+
+Filter_by_label_two_labels
+ When I send a GET request: /catalog-search?q=&label[]=${label.new.name}&label[]=${label.sale.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 65
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${label.new.name}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][1] ${label.sale.name}
+
+Filter_by_label_non_existing_label
+ When I send a GET request: /catalog-search?q=&label[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] test123
+
+Filter_by_label_empty_label
+ When I send a GET request: /catalog-search?q=&label[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${EMPTY}
+
+Filter_by_color_one_color
+ When I send a GET request: /catalog-search?q=&color=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 74
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 7
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] ${color_name}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][0] ${default_qty.categories}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][2] ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_color_two_colors
+ When I send a GET request: /catalog-search?q=&color[]=${color_2}&color[]=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 85
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 8
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 12
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${color_2}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][1] ${color_name}
+
+Filter_by_color_non_existing_color
+ When I send a GET request: /catalog-search?q=&color[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] test123
+
+Filter_by_color_empty_color
+ When I send a GET request: /catalog-search?q=&color[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue][0] ${EMPTY}
+
+Filter_by_valid_main_category
+ When I send a GET request: /catalog-search?q=&category=${category_lvl1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl1.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl1.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][1][docCount] 0
+ And Response body has correct self link
+
+Filter_by_valid_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl2.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl2.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][1][docCount] 0
+ And Array element should contain nested array with property and value at least once: [data][0][attributes][categoryTreeFilter] [children] docCount ${category_lvl2.qty}
+ And Response body has correct self link
+
+Search_with_specific_currency
+ When I send a GET request: /catalog-search?q=¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.chf.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+##### PAGINATION AND SORTING #####
+
+Search_set_specific_page_with_default_ipp
+ # here page 4 is selected using offset because 36/12=3 full pages, search shows the next page after the offset
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.default}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 4
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Search_set_specific_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.middle}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 2
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 9
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.middle}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_last_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.biggest}&page[offset]=${total_number_of_products_in_search_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 6
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 6
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+
+Search_set_invalid_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=18&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${total_number_of_products_in_search_1}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_sort_by_name_asc
+ When I send a GET request: /catalog-search?q=&sort=name_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] A
+ And Response body has correct self link
+
+Search_sort_by_name_desc
+ When I send a GET request: /catalog-search?q=&sort=name_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][2][abstractName] ${concrete_product.product_one_image_set.name}
+ And Response body has correct self link
+
+Search_sort_by_rating
+ When I send a GET request: /catalog-search?q=&sort=rating
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] rating
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_sku_highest_rating}
+ And Response body has correct self link
+
+Search_sort_by_price_asc
+ When I send a GET request: /catalog-search?q=&sort=price_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1800
+ And Response body has correct self link
+
+Search_sort_by_price_desc
+ When I send a GET request: /catalog-search?q=&sort=price_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10000
+ And Response body has correct self link
+
+Search_sort_by_price_filter_query_parameter_and_pagination
+ When I send a GET request: /catalog-search?q=son&sort=price_desc&brand=${brand_4}&page[limit]=${ipp.middle}&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 42
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 2
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 24
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] ${brand_4}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] 345699
+
+Search_by_abstract_sku_with_abstract_include
+ When I send a GET request: /catalog-search?q=${abstract_product_with_alternative.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 3
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][2][abstractName] ${abstract_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-products][data] 3
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][2][id] ${abstract_product_with_alternative.sku}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search_suggestions/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search_suggestions/positive.robot
new file mode 100644
index 0000000..7eb144b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/search_endpoints/catalog_search_suggestions/positive.robot
@@ -0,0 +1,259 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product discontinued-products
+
+*** Test Cases ***
+Get_search_suggestions_without_query_parameter
+ When I send a GET request: /catalog-search-suggestions
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_empty_q_parameter
+ When I send a GET request: /catalog-search-suggestions?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_non_existing_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=000000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_discontinued_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_all_attributes_data
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.name_lower_case}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.name_lower_case}
+ And Each array element of array in response should contain property: [data][0][attributes][categories] name
+ And Each array element of array in response should contain property: [data][0][attributes][categories] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] url
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][abstractSku] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] url
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] url
+ And Response body has correct self link
+
+Get_search_suggestions_with_few_symbols
+ When I send a GET request: /catalog-search-suggestions?q=le
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Each array element of array in response should contain value: [data][0][attributes][completion] le
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] le
+ And Response body has correct self link
+
+Get_search_suggestions_with_11_symbols
+ When I send a GET request: /catalog-search-suggestions?q=acer cb5-31
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 1
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 1
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_concrete_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_pages
+ When I send a GET request: /catalog-search-suggestions?q=${cms_pages.first_cms_page.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${cms_pages.first_cms_page.name_lower_case}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][name] ${cms_pages.first_cms_page.name}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][url] ${cms_pages.first_cms_page.url_en}
+ And Response body has correct self link
+
+Get_search_suggestions_with_category_collection
+ When I send a GET request: /catalog-search-suggestions?q=${category_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][name] ${category_collection_name}
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][url] ${category_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_page_collection
+ When I send a GET request: /catalog-search-suggestions?q=${cms_page_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][name] ${cms_page_collection_name}
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][url] ${cms_page_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_color
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}&color=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_currency
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${brand_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_color
+ When I send a GET request: /catalog-search-suggestions?q=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${color_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku_and_included_abstract_products
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][type] abstract-products
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][type] abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should be: [included][0][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [included][0][attributes][description] ${abstract_available_product_with_stock.description}
+ And Response body parameter should be: [included][0][attributes][attributes][internal_memory] ${internal_memory}
+ And Response body parameter should be: [included][0][attributes][attributes][aspect_ratio] ${aspect_ratio}
+ And Response body parameter should be: [included][0][attributes][attributes][storage_media] ${storage_media}
+ And Response body parameter should be: [included][0][attributes][attributes][display_technology] ${display_technology}
+ And Response body parameter should be: [included][0][attributes][attributes][brand] ${brand_4}
+ And Response body parameter should be: [included][0][attributes][attributes][color] ${color_name}
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributesDefinition] 3
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributes] 0
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][super_attributes] 0
+ And Response body parameter should be: [included][0][attributes][attributeMap][product_concrete_ids] ${concrete_available_product.sku}
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response body parameter should be: [included][0][attributes][metaKeywords] ${concrete_available_product.meta_keywords}
+ And Response body parameter should be: [included][0][attributes][metaDescription] ${concrete_available_product.meta_description}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/negative.robot
new file mode 100644
index 0000000..5c34b38
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_point_addresses
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses
+ Then Response status code should be: 404
+ And Response should return error message: The endpoint is not found.
+
+Retrieves_a_service_point_address_by_not_existing_service_point_and_service_point_address_ids
+ When I send a GET request: /service-points/NonExistId/service-point-addresses/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_existing_service_point_and_not_existing_service_point_address_ids
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_not_existing_service_point_and_existing_service_point_address_ids
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/NonExistId/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_incorrect_url
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-point/${dynamic_service_point_uuid}/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/positive.robot
new file mode 100644
index 0000000..4a96c2a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_point_addresses/positive.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_a_service_point_address_by_id
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [data][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [data][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [data][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [data][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/negative.robot
new file mode 100644
index 0000000..78c1984
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_points_by_incorrect_url
+ When I send a GET request: /service-point
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
+
+Retrieves_a_service_point_by_incorrect_url
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-point/${dynamic_service_point_uuid}
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
+
+Retrieves_a_service_point_by_not_existing_id
+ When I send a GET request: /service-points/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5401
+ And Response should return error message: Service point entity was not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/positive.robot
new file mode 100644
index 0000000..017d283
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/service_point_endpoints/service_points/positive.robot
@@ -0,0 +1,179 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_points
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should NOT be empty: [data] id
+ And Each array element of array in response should NOT be empty: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body should contain: "key": "${dynamic_service.service_point_key}"
+ And Response body should contain: "name": "${dynamic_service.service_point_name}"
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_filtered_by_service_type_key
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?filter[service-points.serviceTypeKey]=${dynamic_service.service_type_key}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_filtered_by_name_using_full_text_search
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?q=${dynamic_service.service_point_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_filtered_by_address_line_1_using_full_text_search
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?q=${dynamic_service.service_point_address_line_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_sort_by_city_asc
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?sort=city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][2][id] ${dynamic_service_point_uuid}
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_sort_by_city_desc
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?sort=-city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_with_addresses_relations
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?include=service-point-addresses&sort=-city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response should contain the array larger than a certain size: [included] 0
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain property with value: [included] type service-point-addresses
+ And Each array element of array in response should contain nested property: [included] [attributes] countryIso2Code
+ And Each array element of array in response should contain nested property: [included] [attributes] address1
+ And Each array element of array in response should contain nested property: [included] [attributes] address2
+ And Each array element of array in response should contain nested property: [included] [attributes] address3
+ And Each array element of array in response should contain nested property: [included] [attributes] zipCode
+ And Each array element of array in response should contain nested property: [included] [attributes] city
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [included][0][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [included][0][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [included][0][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [included][0][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [included][0][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link
+
+Retrieves_a_service_point_by_id
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response body has correct self link internal
+
+Retrieves_a_service_point_by_id_with_address_relation
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}?include=service-point-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [included][0][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [included][0][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [included][0][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [included][0][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [included][0][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link internal
+
+Retrieves_a_service_point_by_id_with_empty_address_relation
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response body should not contain: included
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/negative.robot
new file mode 100644
index 0000000..86b82a4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/negative.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+Get_health_check_with_disabled_services
+### Test works only if all services are disabled as default
+ When I send a GET request: /health-check
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 403
+ And Response body parameter should be: [data][0][attributes][message] HealthCheck endpoints are disabled for all applications.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_invalid_service_name
+ When I send a GET request: /health-check?services=sear
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+Get_health_check_with_empty_service_name
+ When I send a GET request: /health-check?services=
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [data][0][type] health-check
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][status] None
+ And Response body parameter should be: [data][0][attributes][statusCode] 400
+ And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+ And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+ And Response body has correct self link
+
+#Get_health_check_with_non_existing_id
+## The bug https://spryker.atlassian.net/browse/CC-16492 related to the self link and required ID
+ # When I send a GET request: /health-check/1
+ # Then Response status code should be: 200
+ # And Response reason should be: OK
+ # And Response body parameter should be: [data][type] health-check
+ # And Response body parameter should be: [data][id] None
+ # And Response body parameter should be: [data][attributes][status] healthy
+ # And Response body parameter should be: [data][attributes][statusCode] 200
+ # And Response body parameter should be: [data][attributes][message] None
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][0][name] search
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][1][name] storage
+ # And Response body parameter should be: [data][attributes][healthCheckServiceResponses][2][name] zed-request
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] status True
+ # And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] message None
+ ## Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/positive.robot
new file mode 100644
index 0000000..de2262d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/health_checks/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+#Get_health_check_with_all_enabled_services
+ #When I send a GET request: /health-check
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 3
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][1][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][2][name] zed-request
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] status True
+ #And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] message None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_search_service
+ #When I send a GET request: /health-check?services=search
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_storage_service
+ #When I send a GET request: /health-check?services=storage
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] storage
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
+
+#Get_health_check_with_enabled_zed_request_service
+ #When I send a GET request: /health-check?services=zed-request
+ #Then Response status code should be: 200
+ #And Response reason should be: OK
+ #And Response body parameter should be: [data][0][type] health-check
+ #And Response body parameter should be: [data][0][id] None
+ #And Response body parameter should be: [data][0][attributes][status] healthy
+ #And Response body parameter should be: [data][0][attributes][statusCode] 200
+ #And Response body parameter should be: [data][0][attributes][message] None
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] zed-request
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+ #And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+ #And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..09d7420
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/negative.robot
@@ -0,0 +1,12 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response should return error code: 601
+ And Response should return error message: Store not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..96bec0d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/stores/positive.robot
@@ -0,0 +1,119 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+#get
+Get_all_available_stores
+ [Tags] dms-off
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] timeZone
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] code
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_all_available_stores_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] regions
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ [Tags] dms-off
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should not be EMPTY: [data][attributes][timeZone]
+ And Response body parameter should have datatype: [data][attributes][timeZone] str
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] code ${locale.DE.code} ${locale.EN.code}
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][locales] code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
+
+Get_store_by_id_dms_on
+ [Tags] dms-on
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain property: [data][attributes][countries] regions
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/negative.robot
new file mode 100644
index 0000000..85a841b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_url_collection_by_empty_url
+ When I send a GET request: /url-resolver
+ Then Response status code should be: 422
+ And Response should return error code: 2801
+ And Response should return error message: Url request parameter is missing.
+
+Get_url_collection_when_requested_url_does_not_exist
+ When I send a GET request: /url-resolver?url=/requested/url/does/not/exist/
+ Then Response status code should be: 404
+ And Response should return error code: 2802
+ And Response should return error message: Url not found.
+
+
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/positive.robot
new file mode 100644
index 0000000..83de67f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/utility_endpoints/url_resolver/positive.robot
@@ -0,0 +1,52 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_url_collections_by_url_paramater_of_category_nodes
+ When I send a GET request: /url-resolver?url=${url_resolver.category_nodes_url}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.category_nodes_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.category_nodes_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_product
+ When I send a GET request: /url-resolver?url=${url_resolver.abstract_product}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.product_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.product_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_cms_page
+ When I send a GET request: /url-resolver?url=${url_resolver.cms_url}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver.cms_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver.cms_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_parameters_returns_id
+ [Documentation] CC-16595 API: ID is missing from url resolver.
+ [Tags] skip-due-to-issue
+ When I send a GET request: /url-resolver?url=${url_resolver.category_nodes_url}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ When I send a GET request: /url-resolver?url=${url_resolver.abstract_product}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ When I send a GET request: /url-resolver?url=${url_resolver.cms_url}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/negative.robot
new file mode 100644
index 0000000..fe9a26a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/negative.robot
@@ -0,0 +1,449 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist product marketplace-product-offer marketplace-product configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+Adding_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Adding_item_in_wishlist_by_without_Access_Token
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Adding_item_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.sku}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "SK123445666"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_after_enter_space_in_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": " "}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/Mywishlist/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+
+Adding_item_without_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists//wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Adding_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_deactivated_item_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "Demo-SKU-Id"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${concrete_available_product.with_stock}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Deleting_item_in_wishlist_by_without_Access_Token
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${concrete_available_product.with_stock}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Deleting_item_in_wishlist_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Delete_wishlist_item_from_already_deleted_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/${concrete_available_product.with_stock}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_with_invalid_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/Mywishlist/wishlist-items/${concrete_available_product.with_stock}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_without_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists//wishlist-items/${concrete_available_product.with_stock}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Deleting_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_item_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${wishlist_item_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#CC-16642
+Deleting_concrete_product_by_abstract_product_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.sku}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 208
+ And Response should return error message: No item with provided sku in wishlist.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.with_stock}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration_and_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.with_stock}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_item_id2
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [included][1][id] ${ wishlist_item_id2}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should not be blank."
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_aconfigurable_product_with_missing_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This field is missing."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"test","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":1,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":"True","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be of type numeric.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_wishlist_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/positive.robot
new file mode 100644
index 0000000..a4668c2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlist_items/positive.robot
@@ -0,0 +1,409 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist product marketplace-product-offer marketplace-product prices configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+Adding_item_in_wishlist
+ [Documentation] CC-16555 API: JSON response is missing product availability and price
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantReference]
+ And Response body parameter should be: [data][attributes][productOfferReference] None
+ And Response body parameter should be: [data][type] wishlist-items
+ And Response body parameter should be: [data][id] ${wishlist_items_id}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.with_stock}
+ And Response body parameter should be: [data][attributes][id] ${wishlist_items_id}
+ And Response body parameter should not be EMPTY: [data][attributes][availability]
+ And Response body parameter should not be EMPTY: [data][attributes][prices]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Post
+Adding_item_in_wishlist_with_offer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_offer}", "productOfferReference": "offer170"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantReference]
+ And Response body parameter should not be EMPTY: [data][attributes][productOfferReference]
+ And Response body parameter should be: [data][type] wishlist-items
+ And Response body parameter should be: [data][id] ${wishlist_items_id}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.with_offer}
+ And Response body parameter should be: [data][attributes][id] ${wishlist_items_id}
+ And Response body parameter should not be EMPTY: [data][attributes][availability]
+ And Response body parameter should not be EMPTY: [data][attributes][prices]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+
+Adding_multiple_variant_of_abstract_product_in_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_product.product_with_multiple_variants.variant1_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_product.product_with_multiple_variants.variant2_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][1]
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_from_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_offer}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Add_a_configurable_product_with_first_product_variant_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][type] wishlist-items
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][id] ${WishListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be: [included][1][id] ${WishListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_second_product_variant_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][type] wishlist-items
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][id] ${WishListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be: [included][1][id] ${WishListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][id] ${WishListItemId}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"10.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"10.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.11.2029\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.12.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId2
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 4
+ And Response body parameter should be in: [included][0][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][0][id] ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][type] wishlist-items concrete-products
+ And Response body parameter should be in: [included][1][id] ${WishListItemId} ${WishListItemId2}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_2} ${configurable_product.sku_1}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response body parameter should be in: [included][2][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][2][id] ${configurable_product.sku_2} ${configurable_product.sku_1}
+ And Response body parameter should be in: [included][3][type] wishlist-items concrete-products
+ And Response body parameter should be in: [included][3][id] ${WishListItemId2} ${WishListItemId}
+ And Response body parameter should be in: [included][3][attributes][sku] ${configurable_product.sku_2} ${configurable_product.sku_1}
+ And Response body parameter should be in: [included][3][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be in: [included][3][attributes][productConfigurationInstance][isComplete] True False
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_product_variant_of_Configurable_products_without_configurations_and_set_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.12.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId2
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be: [included][0][type] wishlist-items
+ And Response body parameter should be in: [included][0][id] ${WishListItemId} ${WishListItemId2}
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be in: [included][1][id] ${WishListItemId2} ${WishListItemId}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_1} ${configurable_product.sku_2}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: wishlist-items
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId2}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.with_stock}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${WishListItemId} ${wishlist_items_id2}
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku_1} ${concrete_available_product.with_stock}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] displayData {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] isComplete True
+ And Response body parameter should be in: [included][1][id] ${wishlist_items_id2} ${WishListItemId}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku_1} ${concrete_available_product.with_stock}
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_2}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_2}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku_1}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId1
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku_1}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_stock}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.with_stock}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${concrete_available_product.with_stock}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_available_product.with_stock}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/negative.robot
new file mode 100644
index 0000000..af02295
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/negative.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue wishlist marketplace-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+#Get_request
+Getting_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=abc
+ When I send a GET request: /wishlists
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Getting_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /wishlists
+ And Response should return error code: 002
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Getting_wishlist_with_invalid_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /wishlists/2345hasd
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Creating_wishlist_with_missing_name
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+
+
+Creating_wishlist_with_space_in_name
+ Run Keywords I GET access token for the customer: ${yves_second_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": " "}}}
+ And Response status code should be: 400
+ And Response should return error code: 210
+ And Response should return error message: Please enter name using only letters, numbers, underscores, spaces or dashes.
+
+Creating_Wishlist_with_a_name_that_already_exists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 400
+ And Response should return error message: A wishlist with the same name already exists.
+ AND Response should return error code: 202
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/positive.robot
new file mode 100644
index 0000000..78a59f4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/glue/wishlist_endpoints/wishlists/positive.robot
@@ -0,0 +1,179 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist customer-access customer-account-management acl
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Create_a_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ I send a POST request: /wishlists {"data":{"type":"wishlists","attributes":{"name":"${wishlist_name}"}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][id] wishlistId
+ And Response body parameter should be: [data][id] ${wishlistId}
+ And Response body parameter should be: [data][attributes][name] ${wishlist_name}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Save value to a variable: [data][attributes][createdAt] createdAt
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ AND Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlistId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Retrieves_wishlists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a POST request: /wishlists {"data":{"type":"wishlists","attributes":{"name":"${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a GET request: /wishlists
+ Then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response body parameter should not be EMPTY: [links][self]
+ And Each array element of array in response should contain property with value: [data] type wishlists
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] numberOfItems
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlistId}
+... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Getting_wishlists_for_customer_with_no_wishlists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a GET request: /wishlists
+ Then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response should contain the array of a certain size: [data] 0
+ AND Response body has correct self link
+
+Retrieves_wishlist_data_by_id
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response body parameter should be: [data][type] wishlists
+ AND Response body parameter should be: [data][attributes][name] ${random}
+ AND Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ AND Response body parameter should not be EMPTY: [data][id]
+ AND Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ AND Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ AND Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+# #Get_Request
+
+Retrieves_wishlist_with_items
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0][id]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+
+Updates_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "himanshupal"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a PATCH request: /wishlists/${wishlist_id} {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ AND Response body parameter should be: [data][attributes][name] ${random}
+ AND Response body parameter should be: [data][type] wishlists
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Removes_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlists_id
+ When I send a DELETE request: /wishlists/${wishlists_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /wishlists/${wishlists_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+
+Wishlist_Product_Labels
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products,product-labels
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: product-labels
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Retrieves_wishlist_with_items_in_concreate
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ AND Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ AND Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..6da845a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found
diff --git a/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..4ff5077
--- /dev/null
+++ b/atest/testdata/performance/tests/api/mp_b2c/sapi/utility_endpoints/stores/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi
+
+*** Test Cases ***
+Get_all_available_stores
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/negative.robot
new file mode 100644
index 0000000..ce6eb25
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/negative.robot
@@ -0,0 +1,396 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags bapi product category-management merchant-category prices spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Get_product_abstract_collection_with_invalid_query_parameter:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=test
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+
+Create_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH INVALID CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+
+Create_product_abstract_collection_with_correct_child_and_child_contained_invalid_field_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}, {"fk_tax_set": 1, "attributes": "FOO1", "sku": "FOO1", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR1", "sku": "FOOBAR1"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Response body parameter should be: [errors][0][status] 400
+ And Response body parameter should be: [errors][0][code] 1311
+ And Response body parameter should be: [errors][0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ And Response body parameter should be: [data][0][sku] FOO1
+ And Response body parameter should be: [data][0][attributes] FOO1
+ ### GET PRODUCT ABSTRACT WITH CHILDREN ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] FOO1
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][id_product] ${id_product}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Update_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1310
+ And Response body parameter should be: [0][message] Incomplete Request - missing identifier for `robot-tests-product-abstracts0.robot-tests-products0`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_invalid_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProductsInvalid": [{"id_product": ${id_product}, "attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1313
+ And Response body parameter should be: [0][message] Relation `robotTestsProductAbstractProductsInvalid` not found. Please check the requested relation name and try again.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_child_contained_invalid_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR", "sku": "FOOBAR", "invalid_field": "invalid"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should be: [0][message] The provided `robot-tests-product-abstracts0.robot-tests-products0.invalid_field` is incorrect or invalid.
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Upsert_product_abstract_collection_with_missing_required_field:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH INVALID CHILD CONTAINED INVALID FIELD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"fk_product_abstract": ${id_product_abstract}, "attributes": "FOOBAR"}]}]}
+ Then Response status code should be: 400
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should be: [0][message] The required field must not be empty. Field: `robot-tests-product-abstracts0.robot-tests-products0.sku`
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_country_collection_with_existing_child_entity
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_product_abstract_by_id_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST PRODUCT ABSTRACT ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+
+Delete_product_abstract_collection_with_existing_child_entity:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","isDeletable": true,"fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","isDeletable": true,"fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.sku]={"in": ["001","002", "003"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ #### DELETE PRODUCT ABSTRACT BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.sku]={"in": ["001","002", "003"]}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be in: [0][message] Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_price_product`. Failed to delete the data for `robot-tests-product-abstracts.id_product_abstract = ${id_product_abstract}`. The entity has a child entity and can not be deleted. Child entity: `spy_product_abstract_to_product_abstract_type`.
+ And Response body parameter should be: [0][code] 1317
+ And Response body parameter should be: [0][status] 400
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?filter[product-abstracts.sku]={"in": ["001","002", "003"]}
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 3
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
diff --git a/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/positive.robot
new file mode 100644
index 0000000..a4fa142
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/complex/positive.robot
@@ -0,0 +1,400 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+Test Tags bapi product category-management merchant-category prices spryker-core spryker-core-back-office
+
+*** Test Cases ***
+ Get_product_abstract_collection_with_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Delete dynamic entity configuration in Database: robot-tests-product-prices
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ Trigger p&s
+ And I set Headers: Content-Type=application/json Store=DE Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Each array element of array in response should contain property: [data] id_product_abstract
+ And Each array element of array in response should contain property: [data] sku
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] id_product
+ And Each array element of array in response should contain nested property: [data] [robotTestsProductAbstractProducts] fk_product_abstract
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 228
+ And Response should contain the array of a certain size: [data][0] 9
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][0][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Get_product_abstract_with_childs_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-categories spy_category 1 {"identifier":"id_category","fields":[{"fieldName":"id_category","fieldVisibleName":"id_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category_template","fieldVisibleName":"fk_category_template","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"category_key","fieldVisibleName":"category_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_clickable","fieldVisibleName":"is_clickable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_in_menu","fieldVisibleName":"is_in_menu","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-categories robotTestsProductCategories fk_product_abstract id_product
+ Create dynamic entity configuration relation in Database: robot-tests-product-categories robot-tests-categories robotTestsCategories id_category fk_category
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS ONE LVEL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response body parameter should be: [data][id_product_abstract] 130
+ And Response body parameter should be: [data][sku] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][0][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][1][fk_product_abstract] 130
+ And Response body parameter should be: [data][robotTestsProductAbstractProducts][2][fk_product_abstract] 130
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/130?include=robotTestsProductAbstractProducts.robotTestsProductCategories.robotTestsCategories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data] 9
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts] 3
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][0][robotTestsProductCategories][0][robotTestsCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories] 1
+ And Response should contain the array of a certain size: [data][robotTestsProductAbstractProducts][1][robotTestsProductCategories][0][robotTestsCategories] 1
+
+ Create_and_update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductCategories
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-products
+ Delete dynamic entity configuration in Database: robot-tests-product-categories
+ Delete dynamic entity configuration in Database: robot-tests-categories
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_update_product_abstract_collection_with_product_abstract_localized_attributes:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH PRODUCT ABSTRACT LOCALIZED ATTRIBUTES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":1,"approval_status":"approved","attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"testtesttest","color_code":"#DC2E09","robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"{'color':'green'}","description":"childtesttesttest","name":"childtesttesttest","meta_description":"childtesttesttest","meta_keywords":"childtesttesttest","meta_title":"childtesttesttest"}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] testtesttest
+ And Response body parameter should be: [data][0][robotTestsProductAbstractLocalizedAttributes][0][name] childtesttesttest
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractLocalizedAttributes][0][id_abstract_attributes] id_abstract_attributes
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractLocalizedAttributes][0][id_abstract_attributes] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractLocalizedAttributes][0][fk_product_abstract] ${id_product_abstract}
+
+ ### GET PRODUCT ABSTRACT COLLECTION WITH CHILDS AS TREE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract}?include=robotTestsProductAbstractLocalizedAttributes
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][id_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][sku] testtesttest
+ And Response body parameter should be: [data][robotTestsProductAbstractLocalizedAttributes][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][robotTestsProductAbstractLocalizedAttributes][0][name] childtesttesttest
+ And Verify that url is present in the Database: /de-de/testtesttest-${id_product_abstract}
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts/${id_product_abstract} {"data":{"sku":"testtesttest1","robotTestsProductAbstractLocalizedAttributes":[{"name":"childtesttesttest1","id_abstract_attributes":${id_abstract_attributes}}]}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][sku] testtesttest1
+ And Response body parameter should be: [data][robotTestsProductAbstractLocalizedAttributes][0][name] childtesttesttest1
+
+ [Teardown] Run Keywords Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+
+ Create_product_abstract_collection_with_two_childs:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE PRODUCT ABSTRACT WITH TWO CHILDS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}], "robotTestsProductPrices": [{"fk_price_type": 1, "price": 0}]}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO2
+ And Response body parameter should be: [data][0][attributes] FOO
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR2
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR
+ Response body parameter should be greater than : [data][0][id_product_abstract] 0
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ When Save value to a variable: [data][0][robotTestsProductPrices][0][id_price_product] id_price_product
+ Response body parameter should be greater than : [data][0][robotTestsProductAbstractProducts][0][id_product] 0
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][fk_product_abstract] ${id_product_abstract}
+ And Response body parameter should be: [data][0][robotTestsProductPrices][0][fk_product_abstract] ${id_product_abstract}
+
+ [Teardown] Run Keywords Delete product_price by id_price_product in Database: ${id_price_product}
+ ... AND Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+ Update_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Upsert_product_abstract_collection_with_child:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"boolean","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-prices spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-prices robotTestsProductPrices fk_product_abstract id_product_abstract
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH CHILD ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"fk_tax_set": 1, "attributes": "FOO", "sku": "FOO2", "robotTestsProductAbstractProducts": [{"attributes": "FOOBAR", "sku": "FOOBAR2"}]}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ When Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ ### UPDATE PRODUCT ABSTRACT WITH CHILD ###
+ And I send a PUT request: /dynamic-entity/robot-tests-product-abstracts {"data": [{"id_product_abstract": ${id_product_abstract}, "fk_tax_set": 1, "attributes": "FOO_UPDATED", "sku": "FOO_UPDATED", "robotTestsProductAbstractProducts": [{"id_product": ${id_product}, "fk_product_abstract": ${id_product_abstract},"attributes": "FOOBAR_UPDATED", "sku": "FOOBAR_UPDATED"}]}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][sku] FOO_UPDATED
+ And Response body parameter should be: [data][0][approval_status] None
+ And Response body parameter should be: [data][0][new_to] None
+ And Response body parameter should be: [data][0][color_code] None
+ And Response body parameter should be: [data][0][attributes] FOO_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][sku] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][attributes] FOOBAR_UPDATED
+ And Response body parameter should be: [data][0][robotTestsProductAbstractProducts][0][discount] None
+
+ [Teardown] Run Keywords Delete product by id_product in Database: ${id_product}
+ ... AND Delete product_abstract by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductPrices
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-prices
+
+Create_and_publish_complex_product_with_child_relations:
+ [Documentation] As the tech dept, we need to adjust this test to check in /catalog-search as well.
+ ### SETUP DYNAMIC ENTITY CONFIGURATION AND RELATION ###
+ Create dynamic entity configuration in Database: robot-tests-product-abstracts spy_product_abstract 1 {"identifier":"id_product_abstract","fields":[{"fieldName":"id_product_abstract","fieldVisibleName":"id_product_abstract","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_tax_set","fieldVisibleName":"fk_tax_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"approval_status","fieldVisibleName":"approval_status","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"new_from","fieldVisibleName":"new_from","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"new_to","fieldVisibleName":"new_to","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"color_code","fieldVisibleName":"color_code","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-products spy_product 1 {"identifier":"id_product","fields":[{"fieldName":"id_product","fieldVisibleName":"id_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"discount","fieldVisibleName":"discount","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_quantity_splittable","fieldVisibleName":"is_quantity_splittable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"sku","fieldVisibleName":"sku","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"warehouses","fieldVisibleName":"warehouses","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-stock-products spy_stock_product 1 {"identifier":"id_stock_product","fields":[{"fieldName":"id_stock_product","fieldVisibleName":"id_stock_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"quantity","fieldVisibleName":"quantity","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_never_out_of_stock","fieldVisibleName":"is_never_out_of_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_stock","fieldVisibleName":"fk_stock","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-searches spy_product_search 1 {"identifier":"id_product_search","fields":[{"fieldName":"id_product_search","fieldVisibleName":"id_product_search","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product","fieldVisibleName":"fk_product","type":"integer","isCreatable":true,"isEditable":true,"validation":{"isRequired":true}},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_searchable","fieldVisibleName":"is_searchable","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-localized-attributes spy_product_localized_attributes 1 {"identifier":"id_product_attributes","fields":[{"fieldName":"id_product_attributes","fieldVisibleName":"id_product_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-stores spy_product_abstract_store 1 {"identifier":"id_product_abstract_store","fields":[{"fieldName":"id_product_abstract_store","fieldVisibleName":"id_product_abstract_store","isCreatable":false,"isEditable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relations spy_product_relation 1 {"identifier":"id_product_relation","fields":[{"fieldName":"id_product_relation","fieldVisibleName":"id_product_relation","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_relation_type","fieldVisibleName":"fk_product_relation_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"is_active","fieldVisibleName":"is_active","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"is_rebuild_scheduled","fieldVisibleName":"is_rebuild_scheduled","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"product_relation_key","fieldVisibleName":"product_relation_key","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"query_set_data","fieldVisibleName":"query_set_data","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-relation-stores spy_product_relation_store 1 {"identifier":"id_product_relation_store","fields":[{"fieldName":"id_product_relation_store","fieldVisibleName":"id_product_relation_store","isCreatable":true,"isEditable":true,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_product_relation","fieldVisibleName":"fk_product_relation","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-products spy_price_product 1 {"identifier":"id_price_product","fields":[{"fieldName":"id_price_product","fieldVisibleName":"id_price_product","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_type","fieldVisibleName":"fk_price_type","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"price","fieldVisibleName":"price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-stores spy_price_product_store 1 {"identifier":"id_price_product_store","fields":[{"fieldName":"id_price_product_store","fieldVisibleName":"id_price_product_store","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_currency","fieldVisibleName":"fk_currency","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_price_product","fieldVisibleName":"fk_price_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_store","fieldVisibleName":"fk_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"gross_price","fieldVisibleName":"gross_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"net_price","fieldVisibleName":"net_price","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-price-product-defaults spy_price_product_default 1 {"identifier":"id_price_product_default","fields":[{"fieldName":"id_price_product_default","fieldVisibleName":"id_price_product_default","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_price_product_store","fieldVisibleName":"fk_price_product_store","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-categories spy_product_category 1 {"identifier":"id_product_category","fields":[{"fieldName":"id_product_category","fieldVisibleName":"id_product_category","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_category","fieldVisibleName":"fk_category","isCreatable":true,"isEditable":true,"validation":{"isRequired":true},"type":"integer"},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"product_order","fieldVisibleName":"product_order","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes spy_product_abstract_localized_attributes 1 {"identifier":"id_abstract_attributes","fields":[{"fieldName":"id_abstract_attributes","fieldVisibleName":"id_abstract_attributes","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"attributes","fieldVisibleName":"attributes","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"description","fieldVisibleName":"description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true}},{"fieldName":"meta_description","fieldVisibleName":"meta_description","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_keywords","fieldVisibleName":"meta_keywords","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"meta_title","fieldVisibleName":"meta_title","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-label-product-abstracts spy_product_label_product_abstract 1 {"identifier":"id_product_label_product_abstract","fields":[{"fieldName":"id_product_label_product_abstract","fieldVisibleName":"id_product_label_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"fk_product_label","fieldVisibleName":"fk_product_label","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}}]}
+ Create dynamic entity configuration in Database: robot-tests-product-image-sets spy_product_image_set 1 {"identifier":"id_product_image_set","fields":[{"fieldName":"id_product_image_set","fieldVisibleName":"id_product_image_set","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"fk_product","fieldVisibleName":"fk_product","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}},{"fieldName":"name","fieldVisibleName":"name","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":false}},{"fieldName":"fk_product_abstract","fieldVisibleName":"fk_product_abstract","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-products robotTestsProductAbstractProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-stores robotTestsProductAbstractStores fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-relations robotTestsProductRelations fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-relations robot-tests-product-relation-stores robotTestsProductRelationStores fk_product_relation id_product_relation
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-price-products robotTestsProductAbstractPriceProducts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-price-products robot-tests-price-product-stores robotTestsPriceProductStores fk_price_product id_price_product
+ Create dynamic entity configuration relation in Database: robot-tests-price-product-stores robot-tests-price-product-defaults robotTestsPriceProductStoreDefaults fk_price_product_store id_price_product_store
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-categories robotTestsProductAbstractCategories fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-abstract-localized-attributes robotTestsProductAbstractLocalizedAttributes fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-label-product-abstracts robotTestsProductLabelProductAbstracts fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-product-abstracts robot-tests-product-image-sets robotTestsProductImageSets fk_product_abstract id_product_abstract
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-searches robotTestsProductSearch fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-stock-products robotTestsProductStocks fk_product id_product
+ Create dynamic entity configuration relation in Database: robot-tests-products robot-tests-product-localized-attributes robotTestsProductLocalizedAttributes fk_product id_product
+
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### SAVE PRODUCT ABSTRACT WITH STOCK ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-tests-product-abstracts {"data":[{"fk_tax_set":2,"approval_status":"approved","attributes":"{}","new_to":"2028-01-01 00:00:00.000000","sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec","color_code":"#DC2E09","robotTestsProductAbstractProducts":[{"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1 test attributes","is_active":1,"is_quantity_splittable":1,"sku":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","robotTestsProductSearch":[{"fk_locale":66,"is_searchable":1}, {"fk_locale":46,"is_searchable":1}],"robotTestsProductStocks":[{"fk_stock":1,"is_never_out_of_stock":1,"quantity":10}],"robotTestsProductLocalizedAttributes":[{"fk_locale":66,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"attributes":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1","description":"desc","name":"Test Concrete Product d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}],"robotTestsProductAbstractStores":[{"fk_store":1}],"robotTestsProductRelations":[{"fk_product_relation_type":1,"is_active":1,"is_rebuild_scheduled":1,"product_relation_key":"Prk-d04e93a4-29ea-4c48-96ab-e87416aefbec","query_set_data":"","robotTestsProductRelationStores":[{"fk_store":1}]}],"robotTestsProductAbstractPriceProducts":[{"fk_price_type":1,"price":1000,"robotTestsPriceProductStores":[{"fk_currency":93,"fk_store":1,"gross_price":9999,"net_price":8999,"robotTestsPriceProductStoreDefaults":[{}]}]}],"robotTestsProductAbstractCategories":[{"fk_category":5,"product_order":16}],"robotTestsProductAbstractLocalizedAttributes":[{"fk_locale":66,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"},{"fk_locale":46,"attributes":"test","description":"Beeindruckende Aufnahmen","meta_description":"Beeindruckende Aufnahmen","meta_keywords":"Entertainment Electronics","meta_title":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec","name":"test product d04e93a4-29ea-4c48-96ab-e87416aefbec"}],"robotTestsProductLabelProductAbstracts":[{"fk_product_label":1}],"robotTestsProductImageSets":[{"fk_locale":66,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}, {"fk_locale":46,"name":"d04e93a4-29ea-4c48-96ab-e87416aefbec-1"}]}]}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][0][id_product_abstract] id_product_abstract
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][id_product] id_product
+ And Save value to a variable: [data][0][sku] abstract_sku
+ And Save value to a variable: [data][0][robotTestsProductAbstractProducts][0][sku] concrete_sku
+ Trigger p&s
+ Trigger p&s
+ Trigger p&s
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ I set Headers: Content-Type=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /abstract-products/${abstract_sku}/abstract-product-availabilities
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] d04e93a4-29ea-4c48-96ab-e87416aefbec
+
+ I set Headers: Content-Type=application/vnd.api+json Accept=application/vnd.api+json Accept-Language=de-DE, en;q=0.9
+ I send a GET request: /concrete-products/${concrete_sku}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ And Response body parameter should be: [data][attributes][sku] d04e93a4-29ea-4c48-96ab-e87416aefbec-1
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-tests-product-searches?filter[product-searches.fk_product]=${id_product}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][0][id_product_search] id_product_search_first
+ And Save value to a variable: [data][1][id_product_search] id_product_search_second
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-tests-product-searches {"data": [{"id_product_search": ${id_product_search_first},"is_searchable": 0}, {"id_product_search": ${id_product_search_second},"is_searchable": 0}]}
+ Then Response status code should be: 200
+ Trigger p&s
+ Trigger p&s
+ [Teardown] Run Keywords Delete complex product by id_product_abstract in Database: ${id_product_abstract}
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductSearch
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductStocks
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductImageSets
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductLabelProductAbstracts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractLocalizedAttributes
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractCategories
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStoreDefaults
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsPriceProductStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractPriceProducts
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelationStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductRelations
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractStores
+ ... AND Delete dynamic entity configuration relation in Database: robotTestsProductAbstractProducts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-image-sets
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-label-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-categories
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-defaults
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-product-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-price-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relation-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-relations
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstract-stores
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-localized-attributes
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
+ ... AND Delete dynamic entity configuration in Database: robot-tests-stock-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-products
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-abstracts
+ ... AND Delete dynamic entity configuration in Database: robot-tests-product-searches
diff --git a/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/negative.robot
new file mode 100644
index 0000000..2f7a2ca
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/negative.robot
@@ -0,0 +1,451 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Get_list_of_country_with_invalid_token
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID TOKEN ###
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_prefix
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE PREFIX ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity-invalid/robot-test-countries
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET WITH INVALID RESOURCE NAME ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/invalid-resource
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Not found
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 007
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_list_of_country_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/countries/9999999
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_body
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY BODY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_json
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY JSON ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_empty_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH EMPTY DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/countries {"data": []}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid or missing data format. Please ensure that the data is provided in the correct format
+ And Response body parameter should be: [0][code] 1301
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [0][code] 1307
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_valid_and_invalid_data_non_transactional
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","name":"XXX"}, {"iso2_code":"XX", "iso3_code":"XXX", "name":"Country XXX"}]}
+ Then Response status code should be: 201
+ And Response body parameter should contain: [errors][0][message] The required field must not be empty. Field: `robot-test-countries0.iso3_code`
+ And Response body parameter should be: [errors][0][code] 1307
+ And Response body parameter should contain: [errors][0][status] 400
+ And Response body parameter should contain: [data][0][iso2_code] XX
+ And Response body parameter should contain: [data][0][iso3_code] XXX
+ When Save value to a variable: [data][0][id_country] country_id
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_resource_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID RESOURCE NAME ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/cnt {"data":[{"iso2_code":"XX","name":"XXX"}]}
+ Then Response status code should be: 404
+ And Response body parameter should contain: [0][message] Not found
+ And Response body parameter should be: [0][code] 007
+ And Response body parameter should contain: [0][status] 404
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_country_with_invalid_field_value
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID FIELD VALUE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"X","iso3_code":"XXXX","name":""}]}
+ Then Response status code should be: 400
+ And Response should contain the array of a certain size: $ 3
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should contain: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries0` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should contain: [1][status] 400
+ And Response body parameter should contain: [2][message] Invalid data value `robot-test-countries0` for field: `name`.
+ And Response body parameter should be: [2][code] 1306
+ And Response body parameter should contain: [2][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: X
+
+Create_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Create_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url", "fk_locale": 46}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_url_with_invalid_url_name
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete url by url name in Database: test-url
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls {"data":[{"url":"test-url"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The URL is invalid. `robot-test-urls0` field `url` must have a URL data format.
+ And Response body parameter should be: [0][code] 1316
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: test-url
+
+Update_country_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] XXA
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] XXB
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XXXX"}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_collection_with_invalid_data
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY COLLECTION WITH INVALID DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XXXX"},{"id_country":${xxb_country_id},"iso3_code":"XXXXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data value `robot-test-countries0` for field: `iso2_code`.
+ And Response body parameter should be: [0][code] 1306
+ And Response body parameter should be: [0][status] 400
+ And Response body parameter should contain: [1][message] Invalid data value `robot-test-countries1` for field: `iso3_code`.
+ And Response body parameter should be: [1][code] 1306
+ And Response body parameter should be: [1][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field_type
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"XXA"},{"iso2_code":"XB","iso3_code":"XXB","name":"XXB"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ ### UPDATE COUNTRY WITH INVALID FILELD TYPE ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name": "FOO", "iso2_code":1234, "iso3_code": 1234}}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] Invalid data type `robot-test-countries0` for field `iso2_code`
+ And Response body parameter should be: [0][code] 1305
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+
+Update_country_with_invalid_field
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### POST WITH INVALID DATA ###
+ Delete country by iso2_code in Database: XX
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XX","iso3_code":"XXX","name":"XXX"}]}
+ Then Response status code should be: 400
+ And Response body parameter should contain: [0][message] The provided `robot-test-countries0.iso3_code` is incorrect or invalid.
+ And Response body parameter should be: [0][code] 1311
+ And Response body parameter should contain: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Upsert_with_invalid_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### UDATE WITH INVALID ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/1000 {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 400
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Entity `robot-test-countries0.id_country: 1000` not found by identifier, and new identifier can not be persisted. Please update the request.
+ And Response body parameter should be: [0][code] 1308
+ And Response body parameter should be: [0][status] 400
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+
+Delete_country_by_id_is_deletable_false:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": false,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_is_deletable_null:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": null,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Delete_country_by_id_without_is_deletable:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ When Save value to a variable: [data][0][id_country] xxa_id
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 405
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] Method not allowed for the entity `robot-test-countries`.
+ And Response body parameter should be: [0][status] 405
+ And Response body parameter should be: [0][code] 1318
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
diff --git a/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/positive.robot
new file mode 100644
index 0000000..9a65354
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/dynamic_entity/positive.robot
@@ -0,0 +1,579 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/api_dynamic_entity_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office inventory-management marketplace-inventory-management data-exchange-api
+
+*** Test Cases ***
+Get_country_collection
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 6
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] iso3_code ZMB
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_Collection_with_filter_first_item
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER FIRST ITEM ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=AC
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] iso3_code ASC
+ And Array in response should contain property with value: [data] name Ascension Island
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[country.iso2_code]=UA
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_multiple_filter_fields
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}&filter[countries.postal_code_mandatory]=1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_filter_in_condition
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Array in response should contain property with value: [data] iso2_code AD
+ And Array in response should contain property with value: [data] iso3_code AND
+ And Array in response should contain property with value: [data] name Andorra
+ And Array in response should contain property with value: [data] iso2_code AE
+ And Array in response should contain property with value: [data] iso3_code ARE
+ And Array in response should contain property with value: [data] name United Arab Emirates
+ And Array in response should contain property with value: [data] iso2_code UA
+ And Array in response should contain property with value: [data] iso3_code UKR
+ And Array in response should contain property with value: [data] name Ukraine
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_invalid_multiple_filter
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["UA","AD","AE"], "not in": ["AT"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=234&page[limit]=2
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property: [data] iso2_code
+ And Each array element of array in response should contain property: [data] iso3_code
+ And Each array element of array in response should contain property: [data] name
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_collection_with_paginations_out_of_items
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH PAGINATIONS OUT OF ITEMS ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?page[offset]=500&page[limit]=10
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+
+Get_country_collection_with_short_configuration
+ ### SETUP DYNAMIC ENTITY CONFIGURATION WITH LESS NUMBER OF FIELDS ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true}}]}
+ # ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### GET COUNTRY COLLECTION WITH SHORT CONFIGURATION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: [data][0] 3
+ And Array in response should contain property with value: [data] iso2_code AC
+ And Array in response should contain property with value: [data] name Ascension Island
+ And Array in response should contain property with value: [data] iso2_code ZM
+ And Array in response should contain property with value: [data] name Zambia
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Get_country_by_id
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ And I send a POST request with data: /token 'grantType=password&username=admin@spryker.com&password=change123'
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+ When Save value to a variable: [access_token] token
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/1
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should not be EMPTY: [data][iso2_code]
+ And Response body parameter should not be EMPTY: [data][iso3_code]
+ And Response body parameter should not be EMPTY: [data][name]
+ And Response body parameter should not be EMPTY: [data][postal_code_mandatory]
+ [Teardown] Run Keyword Delete dynamic entity configuration in Database: robot-test-countries
+
+Create_and_update_country:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XM
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XM","iso3_code":"XXM","name":"POST XM"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XM
+ And Response body parameter should be: [data][0][iso3_code] XXM
+ And Response body parameter should be: [data][0][name] POST XM
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ ### UPDATE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XX
+ ### UPDATE ONE FIELD OF COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries/${xxa_country_id} {"data":{"name":"Test Country"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Test Country
+ And Response body parameter should be: [data][id_country] ${xxa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Test Country
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XM
+
+Create_and_update_url:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-urls
+ Create dynamic entity configuration in Database: robot-test-urls spy_url 1 {"identifier":"id_url","fields":[{"fieldName":"id_url","fieldVisibleName":"id_url","isCreatable":false,"isEditable":false,"validation":{"isRequired":false},"type":"integer"},{"fieldName":"fk_locale","fieldVisibleName":"fk_locale","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":true}},{"fieldName":"url","fieldVisibleName":"url","isCreatable":true,"isEditable":true,"type":"string","validation":{"isRequired":true,"constraints":[{"name":"url"}]}},{"fieldName":"fk_resource_product_set","fieldVisibleName":"fk_resource_product_set","isCreatable":true,"isEditable":true,"type":"integer","validation":{"isRequired":false}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST URL AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: /test-url/123
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-urls {"data":[{"url":"/test-url/123", "fk_locale": 46}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][url] /test-url/123
+ And Response body parameter should be: [data][0][fk_locale] 46
+ When Save value to a variable: [data][0][id_url] id_url
+ ### UPDATE URL ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-urls/${id_url} {"data":{"url":"/test-url-test/42"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ And Response body parameter should be: [data][id_url] ${id_url}
+ ### GET URL AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-urls/${id_url}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][url] /test-url-test/42
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-urls
+ ... AND Delete url by url name in Database: /test-url-test/42
+
+Create_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Create_country_collection_non_transactional:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE THREE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XXA
+ And Response body parameter should be: [data][0][name] Country XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XXB
+ And Response body parameter should be: [data][1][name] Country XB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ And Response body parameter should be: [data][2][postal_code_regex] \\\\d{5}
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_country_id
+ When Save value to a variable: [data][1][id_country] xxb_country_id
+ When Save value to a variable: [data][2][id_country] xxc_country_id
+ #### UPDATE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type==application/json Authorization=Bearer ${token} X-Is-Transactional=false
+ And I send a PATCH request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xxa_country_id},"iso2_code":"XA","iso3_code":"XAA","name":"XAA"},{"id_country":${xxb_country_id},"iso2_code":"XB","iso3_code":"XBB","name":"XBB"},{"id_country":${xxc_country_id},"iso2_code":"XC","iso3_code":"XCC","name":"XCC"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] XAA
+ And Response body parameter should be: [data][0][id_country] ${xxa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] XBB
+ And Response body parameter should be: [data][1][id_country] ${xxb_country_id}
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XCC
+ And Response body parameter should be: [data][2][name] XCC
+ And Response body parameter should be: [data][2][id_country] ${xxc_country_id}
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Upsert_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### POST GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+
+ ### CREATE TEST COUNTRY AND CLEANUP TEST DATA IF EXIST###
+ Delete country by iso2_code in Database: XA
+ Delete country by iso2_code in Database: XB
+ Delete country by iso2_code in Database: XL
+ Delete country by iso2_code in Database: XS
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XAA","name":"PUT XAA"},{"iso2_code":"XB","iso3_code":"XBB","name":"PUT XBB"}]}
+ Then Response status code should be: 201
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XA
+ And Response body parameter should be: [data][0][iso3_code] XAA
+ And Response body parameter should be: [data][0][name] PUT XAA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ And Response body parameter should be: [data][1][iso2_code] XB
+ And Response body parameter should be: [data][1][iso3_code] XBB
+ And Response body parameter should be: [data][1][name] PUT XBB
+ Response body parameter should be greater than : [data][1][id_country] 200
+ When Save value to a variable: [data][0][id_country] xaa_country_id
+ When Save value to a variable: [data][1][id_country] xbb_country_id
+
+ ## UPSERT ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXX"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXX
+ ### PARTIAL UPDATE ONE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries/${xaa_country_id} {"data":{"iso2_code":"XX","iso3_code":"XXX","name":"Country XXL"}}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][name] Country XXL
+ And Response body parameter should be: [data][id_country] ${xaa_country_id}
+ ### GET COUNTRY AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XX
+ And Response body parameter should be: [data][iso3_code] XXX
+ And Response body parameter should be: [data][name] Country XXL
+ ### UPSERT COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PUT request: /dynamic-entity/robot-test-countries {"data":[{"id_country":${xaa_country_id},"iso2_code":"XL","iso3_code":"XXL","name":"XXL"},{"id_country":${xbb_country_id},"iso2_code":"XS","iso3_code":"XXS","name":"XXS"}]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] XL
+ And Response body parameter should be: [data][0][iso3_code] XXL
+ And Response body parameter should be: [data][0][name] XXL
+ And Response body parameter should be: [data][0][id_country] ${xaa_country_id}
+ And Response body parameter should be: [data][1][iso2_code] XS
+ And Response body parameter should be: [data][1][iso3_code] XXS
+ And Response body parameter should be: [data][1][name] XXS
+ And Response body parameter should be: [data][1][id_country] ${xbb_country_id}
+ ### GET COUNTRIES AND VALIDATE DATA ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xaa_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XL
+ And Response body parameter should be: [data][iso3_code] XXL
+ And Response body parameter should be: [data][name] XXL
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xbb_country_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] XS
+ And Response body parameter should be: [data][iso3_code] XXS
+ And Response body parameter should be: [data][name] XXS
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+ ... AND Delete country by iso2_code in Database: XX
+ ... AND Delete country by iso2_code in Database: XL
+ ... AND Delete country by iso2_code in Database: XS
+
+Delete_country_collection:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRIES ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"},{"iso2_code":"XB","iso3_code":"XXB","name":"Country XB"},{"iso2_code":"XC","iso3_code":"XXC","name":"Country XC","postal_code_regex":"\\\\d{5}"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][2][iso2_code] XC
+ And Response body parameter should be: [data][2][iso3_code] XXC
+ And Response body parameter should be: [data][2][name] Country XC
+ Response body parameter should be greater than : [data][2][id_country] 200
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ When Save value to a variable: [data][0][name] xxa_name
+ When Save value to a variable: [data][1][iso2_code] xxb_iso2_code
+ When Save value to a variable: [data][1][name] xxb_name
+ When Save value to a variable: [data][2][iso2_code] xxc_iso2_code
+ When Save value to a variable: [data][2][name] xxc_name
+ ### GET COUNTRY COLLECTION WITH FILTER ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][0][iso2_code] ${xxa_iso2_code}
+ And Response body parameter should be: [data][0][name] ${xxa_name}
+ And Response body parameter should be: [data][1][iso2_code] ${xxb_iso2_code}
+ And Response body parameter should be: [data][1][name] ${xxb_name}
+ And Response body parameter should be: [data][2][iso2_code] ${xxc_iso2_code}
+ And Response body parameter should be: [data][2][name] ${xxc_name}
+ #### DELETE COUNTRY COLLECTION ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries?filter[countries.iso2_code]={"in": ["${xxa_iso2_code}","${xxb_iso2_code}","${xxc_iso2_code}"]}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response should contain the array of a certain size: $ 1
+ And Response should contain the array of a certain size: [data] 0
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+ ... AND Delete country by iso2_code in Database: XB
+ ... AND Delete country by iso2_code in Database: XC
+
+Delete_country_by_id:
+ ### SETUP DYNAMIC ENTITY CONFIGURATION ###
+ Delete dynamic entity configuration in Database: robot-test-countries
+ Create dynamic entity configuration in Database: robot-test-countries spy_country 1 {"identifier":"id_country","isDeletable": true,"fields":[{"fieldName":"id_country","fieldVisibleName":"id_country","isEditable":false,"isCreatable":false,"type":"integer","validation":{"isRequired":false}},{"fieldName":"iso2_code","fieldVisibleName":"iso2_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":2,"minLength":2}},{"fieldName":"iso3_code","fieldVisibleName":"iso3_code","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":3,"minLength":3}},{"fieldName":"name","fieldVisibleName":"name","type":"string","isEditable":true,"isCreatable":true,"validation":{"isRequired":true,"maxLength":255,"minLength":1}},{"fieldName":"postal_code_mandatory","fieldVisibleName":"postal_code_mandatory","type":"boolean","isEditable":true,"isCreatable":true,"validation":{"isRequired":false}},{"fieldName":"postal_code_regex","isEditable":"false","isCreatable":"false","fieldVisibleName":"postal_code_regex","type":"string","validation":{"isRequired":false,"maxLength":500,"minLength":1}}]}
+ ### GET TOKEN ###
+ I get access token by user credentials: ${zed_admin.email}
+ ### CREATE TEST COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a POST request: /dynamic-entity/robot-test-countries {"data":[{"iso2_code":"XA","iso3_code":"XXA","name":"Country XA"}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][0][iso2_code] XA
+ Response body parameter should be greater than : [data][0][id_country] 200
+ When Save value to a variable: [data][0][id_country] xxa_id
+ When Save value to a variable: [data][0][iso2_code] xxa_iso2_code
+ ### GET COUNTRY BY ID ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [data][iso2_code] ${xxa_iso2_code}
+ #### DELETE COUNTRY ###
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a DELETE request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a GET request: /dynamic-entity/robot-test-countries/${xxa_id}
+ Then Response status code should be: 404
+ And Response header parameter should be: Content-Type application/json
+ And Response body parameter should be: [0][message] The entity `robot-test-countries` could not be found in the database.
+ And Response body parameter should be: [0][status] 404
+ And Response body parameter should be: [0][code] 1303
+ [Teardown] Run Keywords Delete dynamic entity configuration in Database: robot-test-countries
+ ... AND Delete country by iso2_code in Database: XA
+
+Authorization_by_x_api_key
+ [Documentation] data excahnge api should support 2 autorization options: by x-api-key and by backoffice user token.
+ [Setup] Create api key in db
+ When I set Headers: x-api-key=${dummy_api_key}
+ And I send a GET request: /dynamic-entity/categories
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type application/json
+ [Teardown] Delete api key from db
+
+Availability_recalculation_after_stock_update
+ [Documentation] checks that product availability is recalculated after stock update via data exchange api
+ [Setup] Find first available product via data exchange api
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ And I send a PATCH request: /dynamic-entity/stock-products/${index} {"data":{"is_never_out_of_stock":false,"quantity":0}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][is_never_out_of_stock] False
+ And Response body parameter should be: [data][quantity] 0
+ Trigger p&s
+ And Product availability status should be changed on: is_available=False
+ [Teardown] Run Keywords Remove Tags *
+ ... AND Set Tags bapi
+ ... AND Restore product initial stock via data exchange api:
diff --git a/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/negative.robot
new file mode 100644
index 0000000..ea0ca50
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/negative.robot
@@ -0,0 +1,126 @@
+
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi push-notification spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Retrieve_push_notification_providers_without_authorization
+ When I set Headers: Content-Type=application/vnd.api+json
+ And I send a GET request: /push-notification-providers
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_push_notification_providers_with_incorrect_token
+ When I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer incorrect_token
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Retrieve_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a GET request: /push-notification-providers/non-existent-id
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+Create_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+
+Create_push_notification_provider_without_authorization
+ When I set Headers: Content-Type=application/vnd.api+json
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Create_push_notification_provider_with_invalid_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "invalid-type","attributes": {"name": "Invalid Type Push Notification Provider"}}}
+ Then Response status code should be: 400
+ And Response should return error message: Validation issues during the creation
+
+Create_two_push_notification_providers_with_same_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_256_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNamesadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5007
+ And Response should return error message: A push notification provider name must have length from 1 to 255 characters.
+
+Update_push_notification_provider_without_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Wrong request body.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider_with_incorrect_auth
+ [Setup] Run Keywords I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer invalid
+ ... AND I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider"}}}
+ ... AND Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "Unauthorized Push Notification Provider Updated"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_non-existent_push_notification_provider
+ [Documentation]
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a PATCH request: /push-notification-providers/non-existent-uuid {"data": {"type": "push-notification-providers","attributes": {"name": "Non-Existent Push Notification Provider Updated"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5001
+ And Response should return error message: The push notification provider was not found.
+
+ Update_push_notification_provider_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ Then Response status code should be: 201
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id_2} {"data": {"type": "push-notification-providers","attributes": {"name": "Provider1 ${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5008
+ And Response should return error message: A push notification provider with the same name already exists.
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Delete_push_notification_provider_with_not_exist_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ Then I send a DELETE request: /push-notification-providers/invalid
+ Then Response status code should be: 404
diff --git a/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/positive.robot
new file mode 100644
index 0000000..39071de
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_provides/positive.robot
@@ -0,0 +1,140 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi push-notification spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Create_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ And Response body has correct self link for created entity: ${push_notification_provider_id}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Create_push_notification_provider_with_255_characters_in_the_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][attributes][name] testProviderNameadkjhsjkdhsjkdsjdsjdjsdfsdbshajdbshdhsdsadbfsadhjfsajdfhbwehfdnmsabdfmsbdafnmbsadfnmasbdfnabfnasbdfnasdbfsndafbsnadfbsnfbsnfbsndfbsnafbsanfbsanfmbasnfabsfnabsfnas fnceaschgewahcaehewdhdbsadbcashdcdsacsedfseffsfdfedrfreferfferferferferfrfer
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Update_push_notification_provider
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a PATCH request: /push-notification-providers/${push_notification_provider_id} {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider Updated ${random}"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider Updated ${random}
+ And Response body has correct self link internal
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Retrieve_push_notification_providers
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider1 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider2 ${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers
+ Then Response status code should be: 200
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should be: [data][1][type] push-notification-providers
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][uuid]
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_pagination
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ # And I send a DELETE request: /push-notification-providers/${push_notification_provider_uuid}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification1${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My-Push-Notification2${random}"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?page[offset]=1&page[limit]=1
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should be: [data][0][attributes][name] My-Push-Notification1${random}
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_with_sorting
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "A-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "B-My-Push-Notification"}}}
+ Then Save value to a variable: [data][id] push_notification_provider_id_2
+ When I send a GET request: /push-notification-providers?sort=-name
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][name] web-push-php
+ And Response body parameter should be: [data][1][attributes][name] B-My-Push-Notification
+ And Response body parameter should be: [data][2][attributes][name] A-My-Push-Notification
+ [Teardown] Run Keywords I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id_2}
+
+Retrieve_push_notification_provider_by_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/vnd.api+json Authorization=Bearer ${token}
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ When I send a GET request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Response body parameter should be: [data][type] push-notification-providers
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][name] My Push Notification Provider ${random}
+ [Teardown] I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+
+Delete_push_notification_provider_while_push_notification_subscription_exists
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # create a provider for push notification
+ When I send a POST request: /push-notification-providers {"data": {"type": "push-notification-providers","attributes": {"name": "My Push Notification Provider ${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_provider_id
+ And Save value to a variable: [data][attributes][name] push_notification_provider_name
+ # create a subscription
+ Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_provider_name}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ # delete a provider for push notification
+ De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Then I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
+ Then Response status code should be: 400
+ And Response should return error code: 5004
+ And Response should return error message: Unable to delete push notification provider while push notification subscription exists.
+ [Teardown] Run Keywords Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+ ... AND I send a DELETE request: /push-notification-providers/${push_notification_provider_id}
diff --git a/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
new file mode 100644
index 0000000..1ea63ab
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi push-notification spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_incorrect_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"DU_AE"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Provided locale not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
diff --git a/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
new file mode 100644
index 0000000..851b056
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/push_notification_endpoints/push_notification_subscriptions/positive.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/push_notifications_steps.robot
+Test Tags bapi push-notification spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Creates_push_notification_subscription_with_correct_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"},"localeName":"${locale.DE.name}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] ${locale.DE.name}
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses[0].uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
+
+Creates_push_notification_subscription_without_locale
+ [Setup] Run Keywords Create warehouse in DB: ${warehouses[0].name} ${True} ${warehouses[0].uuid}
+ ... AND Assign user to Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ I get access token by user credentials: ${zed_admin.email}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ And I send a POST request: /push-notification-subscriptions {"data":{"type":"push-notification-subscriptions","attributes":{"providerName":"${push_notification_subscriptions[0].providerName}","group":{"name":"${push_notification_subscriptions[0].group.name}","identifier":"${warehouses[0].uuid}"},"payload":{"endpoint":"${push_notification_subscriptions[0].payload.endpoint}","publicKey":"${push_notification_subscriptions[0].payload.publicKey}","authToken":"${push_notification_subscriptions[0].payload.authToken}"}}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] push_notification_subscription_uuid
+ And Response body parameter should be: [data][type] push-notification-subscriptions
+ And Response body parameter should be: [data][attributes][providerName] ${push_notification_subscriptions[0].providerName}
+ And Response body parameter should be: [data][attributes][payload][endpoint] ${push_notification_subscriptions[0].payload.endpoint}
+ And Response body parameter should be: [data][attributes][payload][publicKey] ${push_notification_subscriptions[0].payload.publicKey}
+ And Response body parameter should be: [data][attributes][payload][authToken] ${push_notification_subscriptions[0].payload.authToken}
+ And Response body parameter should be: [data][attributes][localeName] None
+ And Response body parameter should be: [data][attributes][group][name] ${push_notification_subscriptions[0].group.name}
+ And Response body parameter should be: [data][attributes][group][identifier] ${warehouses[0].uuid}
+ [Teardown] Run Keywords De-assign user from Warehouse in DB: ${zed_admin.email} ${warehouses[0].uuid}
+ ... AND Delete warehouse in DB: ${warehouses[0].uuid}
+ ... AND Delete push notification subscription in DB: ${push_notification_subscription_uuid}
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/negative.robot
new file mode 100644
index 0000000..521bc84
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/negative.robot
@@ -0,0 +1,158 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Create_Service_Point_Address_Without_Authentication
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
+
+Create_Service_Point_Address_With_Incorrect_Token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer IncorrectToken
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_Duplicate_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5417
+ And Response should return error message: A service point address for the service point already exists.
+
+Create_Service_Point_address_without_address
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+
+Create_Service_Point_address_with_empty_address
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+
+Create_Service_Point_address_with_not_existing_region
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"regionUuid": "not-existing-rigion-uuid", "countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5410
+ And Response should return error message: Region with uuid 'not-existing-rigion-uuid' does not exist for country with iso2 code 'DE'.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_address_with_not_existing_country
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-45${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "NOTEXIST", "address":"", "address2": "Building №2", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5409
+ And Response should return error message: Country with iso2 code 'DE' does not exist.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+ Create_Service_Point_address_with_zip_more_than_15
+ [Documentation] https://spryker.atlassian.net/browse/CC-29310
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses {"data": {"type": "service-point-addresses", "attributes": {"countryIso2Code": "DE", "address":"", "address2": "Building №2", "zipCode": "30-22111111111112", "city": "Dreamtown"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5415
+ And Response should return error message: A service point address zip code must have length from 1 to 15 characters.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_Address_Without_Authentication
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=
+ When I send a PATCH request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
+
+Update_Service_Point_Address_With_Incorrect_Token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=IncorrectToken
+ When I send a PATCH request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Update_Nonexistent_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/not-existing-service-point/service-point-addresses/NonexistentID {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: Service point address entity was not found.
+
+Update_Service_Point_Address_Invalid_Content_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "invalid", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 404
+
+Update_Service_Point_Address_Nonexistent_Service_Point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/NonexistentID/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
+Update_Service_Point_Address_Invalid_Region
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"regionUuid": "InvalidRegion", "address1": "New Address", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5410
+
+Update_Service_Point_Address_Empty_Zip_Code
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses/${service_point_address.uuid} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address", "zipCode": "", "city": "New City"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5415
+ And Response should return error message: A service point address zip code must have length from 4 to 15 characters.
+
+Retrieve_address_for_Nonexistent_Service_Point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-points/NonexistentID/service-point-addresses
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
+Read_Service_Point_Address_No_Authentication
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a GET request: /service-points/${demo_service_point.spryker_main_store.uuid}/service-point-addresses
+ Then Response status code should be: 403
+ And Response should return error message: Missing access token.
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/positive.robot
new file mode 100644
index 0000000..2e9491a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_point_addresses/positive.robot
@@ -0,0 +1,98 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Create_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №22","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][attributes][address1] Park Avenue
+ And Response body parameter should be: [data][attributes][address2] Building №22
+ And Response body parameter should be: [data][attributes][zipCode] 30-221
+ And Response body parameter should be: [data][attributes][city] Dreamtown
+ And Response body has correct self link for created entity: ${service_point_address_id}
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_Address_with_address_3
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-2${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][attributes][address3] address3
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_Address_with_region_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-3${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ And Create region in DB: 60 DE Germany 123456789
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type":"service-point-addresses","attributes":{"regionUuid":"123456789","address1":"Park Avenue","address2":"Building №2","address3":"address3","city":"Dreamtown","zipCode":"30-221","countryIso2Code":"DE"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should be: [data][attributes][regionUuid] 123456789
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-update-4${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points/${service_point_id}/service-point-addresses {"data":{"type": "service-point-addresses","attributes":{"regionUuid":"123456789", "countryIso2Code": "DE", "address1": "Park Avenue", "address2": "Building №2", "address3": "7th floor", "zipCode": "30-221", "city": "Dreamtown"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_point_address_id
+ When I send a PATCH request: /service-points/${service_point_id}/service-point-addresses/${service_point_address_id} {"data": {"type": "service-point-addresses", "attributes": {"address1": "New Address","address2": "new address2", "address3": "new address3", "zipCode": "40-123", "city": "New City"}}}
+ Then Response status code should be: 200
+ And Save value to a variable: [data][id] service_point_address_id
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][attributes][regionUuid] 123456789
+ And Response body parameter should be: [data][attributes][address1] New Address
+ And Response body parameter should be: [data][attributes][address2] new address2
+ And Response body parameter should be: [data][attributes][address3] new address3
+ And Response body parameter should be: [data][attributes][zipCode] 40-123
+ And Response body parameter should be: [data][attributes][city] New City
+ And Response body has correct self link internal
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Retrieve_Service_Point_Address
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-points/${demo_service_point.spryker_main_store.uuid2}/service-point-addresses
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][type] service-point-addresses
+ And Response body parameter should be: [data][0][id] ${service_point_address.uuid2}
+ And Response body parameter should be: [data][0][attributes][countryIso2Code] DE
+ And Response body parameter should be: [data][0][attributes][uuid] ${service_point_address.uuid2}
+ And Response body parameter should be: [data][0][attributes][address1] ${service_point_address.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${service_point_address.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${service_point_address.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${service_point_address.zip}
+ And Response body parameter should be: [data][0][attributes][city] ${service_point_address.city}
+ And Response body has correct self link
+
+
+
+
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/negative.robot
new file mode 100644
index 0000000..1549d6a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/negative.robot
@@ -0,0 +1,172 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Create_Service_Point_With_Existing_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point Name1","key": "service-point${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point Name2","key": "service-point${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5404
+ And Response should return error message: A service point with the same key already exists.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_Service_Point_With_Invalid_Key_Length
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Incorrect key lenghth","key": "fihslafnkjskdjfnskadfkafkjsadfkjsdjnnkfjsdkfjdskdjfhnjdksbfjhdsbfjkdsfbjsdfjksdfjksdfhdjksfhkdsf jkdsfhjdhsfjhdsjfhdsfjhsjkfhkshkjdsahf78348937489137489yewhkjdsfildksh9832urqewdiosjakrj3982diasjif8d3j89siojfdisakjfdiksdjfkasdjfhkjdashfjkldsahfldchgjhjjghjg2","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5405
+ And Response should return error message: A service point key must have length from 1 to 255 characters.
+
+Create_Service_Point_With_Empty_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "New Service Point", "key": "", "isActive": "true", "stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5405
+ And Response should return error message: A service point key must have length from 1 to 255 characters.
+
+Create_Service_Point_Without_Authorization
+ [Setup] I set Headers: Authorization=
+ When I send a POST request: /service-points {"name": "New Service Point", "key": "new_service_point", "isActive": "true", "stores": ["DE", "AT"]}
+ Then Response status code should be: 403
+
+Create_Service_Point_With_Empty_Name
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1597
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"name": "", "key": "invalid_name_length", "isActive": "true", "stores": ["DE", "AT"]}
+ Then Response status code should be: 400
+ And Response should return error code: 5407
+ And Response should return error message: A service point name must have length from 0 to 255 characters.
+
+Create_Service_Point_With_Invalid_Store
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1597
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"name": "Invalid Store Service Point", "key": "invalid_store", "isActive": "true", "stores": ["Invalid_Store"]}
+ Then Response status code should be: 400
+ And Response should return error code: 5401
+ And Response should return error message: Wrong request body.
+
+Create_Service_Point_With_Empty_Body
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1597
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {}
+ Then Response status code should be: 400
+ And Response should return error code: 5401
+ And Response should return error message: Wrong request body.
+
+Create_Service_Point_With_Invalid_Content_Type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=text/plain Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"name": "Invalid Content Type", "key": "invalid_content_type", "isActive": "true", "stores": ["DE", "AT"]}
+ Then Response status code should be: 400
+ And Response should return error code: 5401
+ And Response should return error message: Wrong request body.
+
+Create_Service_Point_With_Invalid_Token
+ [Setup] I set Headers: Authorization=Bearer InvalidToken
+ When I send a POST request: /service-points {"name": "Invalid Token", "key": "invalid_token", "isActive": "true", "stores": ["DE", "AT"]}
+ Then Response status code should be: 401
+
+Create_Service_Point_With_Missing_Required_Fields
+ [Documentation] https://spryker.atlassian.net/browse/FRW-1597
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"isActive": "true", "stores": ["DE", "AT"]}
+ Then Response status code should be: 400
+ And Response should return error code: 5401
+ And Response should return error message: Wrong request body.
+
+Update_Service_Point_With_Wrong_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Initial Service Point ${random}","key": "initial-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ ... AND Save value to a variable: [data][attributes][key] service_point_key
+ ... AND Save value to a variable: [data][id] service_point_id
+ When I send a PATCH request: /service-points/${service_point_id} {"data": {"type": "invalid-type","attributes": {"key": "initial-service-point-${random}","stores": ["DE"],"isActive": "false","name": "Updated Service Point"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5401
+ And Response should return error message: Wrong request body
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_Without_Authorization
+ [Setup] I set Headers: Authorization=
+ When I send a PATCH request: /service-points/random-id {"data": {"type": "service-points","attributes": {"name": "Unauthorized Update","key": "unauthorized-update-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 403
+
+Update_Service_Point_With_Nonexistent_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-points/nonexistent-id {"data": {"type": "service-points","attributes": {"name": "Nonexistent ID","key": "nonexistent-id-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
+Update_Service_Point_With_incorrect_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer incorrect
+ When I send a PATCH request: /service-points/random-id {"data": {"type": "service-points","attributes": {"name": "Unauthorized Update","key": "unauthorized-update-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 401
+
+Update_Service_Point_With_Empty_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Initial Service Point ${random}","key": "initial-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ ... AND Save value to a variable: [data][attributes][key] service_point_key
+ ... AND Save value to a variable: [data][id] service_point_id
+ When I send a PATCH request: /service-points/${service_point_id} {"data": {"type": "service-points","attributes": {"key": "Initial Service Point ${random}","stores": ["DE"],"isActive": "true","name": ""}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5407
+ And Response should return error message: A service point name must have length from 1 to 255 characters.
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Update_Service_Point_With_not_existing_key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Non Existing Initial Service Point ${random}","key": "non-existing-initial-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ ... AND Save value to a variable: [data][id] service_point_id
+ When I send a PATCH request: /service-points/${service_point_id} {"data": {"type": "service-points","attributes": {"key": "not-existing-key${random}","stores": ["DE"],"isActive": "true","name": "test"}}}
+ Then Response status code should be: 200
+ Save value to a variable: [data][attributes][key] service_point_key
+ # duplicate key is not possible
+ Then I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Initial Service Point ${random}","key": "not-existing-key${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Get_Service_Points_Without_Authentication
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /service-points
+ Then Response status code should be: 403
+
+Get_Service_Points_With_Incorrect_Token
+ [Setup] I set Headers: Authorization=Bearer IncorrectToken
+ When I send a GET request: /service-points
+ Then Response status code should be: 401
+
+Get_Service_Point_By_Nonexistent_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-points/NonexistentID
+ Then Response status code should be: 404
+ And Response should return error code: 5403
+ And Response should return error message: Service point entity was not found.
+
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/positive.robot
new file mode 100644
index 0000000..61ab624
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_points/positive.robot
@@ -0,0 +1,107 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_All_Service_Points
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point 1","key": "some-service-point1-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Save value to a variable: [data][attributes][key] service_point_key1
+ And Save value to a variable: [data][id] service_point_id1
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Service Point 2","key": "some-service-point2-${random}","isActive": "false","stores": ["AT"]}}}
+ Then Save value to a variable: [data][attributes][key] service_point_key2
+ And Save value to a variable: [data][id] service_point_id2
+ When I send a GET request: /service-points
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][type] service-points
+ And Each array in response should contain property with NOT EMPTY value: [data] [id]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][key]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][isActive]
+ And Each array element of array in response should contain property with value in: [data] [attributes][stores] DE AT
+ [Teardown] Run Keywords Deactivate service point via BAPI ${service_point_id1}
+ ... AND Deactivate service point via BAPI ${service_point_id1}
+
+Create_new_service_point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "ANSHO Some Service Point ${random}","key": "some-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Response body parameter should be: [data][type] service-points
+ And Save value to a variable: [data][id] service_point_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] ANSHO Some Service Point ${random}
+ And Response body parameter should be: [data][attributes][key] some-service-point-${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link for created entity: ${service_point_id}
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Create_new_service_point_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Not Unique Name","key": "some-service-point-1${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key_1
+ And Save value to a variable: [data][id] new_service_point_id
+ # Create a new service point with an existing name
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Not Unique Name","key": "another-service-point-2${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][attributes][key] service_point_key_2
+ And Response body parameter should be: [data][type] service-points
+ And Save value to a variable: [data][id] service_point_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] Not Unique Name
+ And Response body parameter should be: [data][attributes][key] ${service_point_key_2}
+ [Teardown] Run Keywords Deactivate service point via BAPI ${new_service_point_id}
+ ... AND Deactivate service point via BAPI ${new_service_point_id}
+
+Create_Service_Point_With_Valid_Key_Length
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Correct key lenghth","key": "fihslafnkjskdjfnskadfkafkjsadfkjsdjnnkfjsdkfjdskdjfhnjdksbfjhdsbfjkdsfbjsdfjksdfjksdfhdjksfhkdsf jkdsfhjdhsfjhdsjfhdsfjhsjkfhkshkjdsahf78348937489137489yewhkjdsfildksh9832urqewdiosjakrj3982diasjif8d3j89siojfdisakjfdiksdjfkasdjfhkjdashfjkldsahfldc${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] new_service_point_id
+ [Teardown] Deactivate service point via BAPI ${new_service_point_id}
+
+Update_Service_Point
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Initial Service Point ${random}","key": "initial-service-point-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ ... AND Save value to a variable: [data][attributes][key] service_point_key
+ ... AND Save value to a variable: [data][id] service_point_id
+ When I send a PATCH request: /service-points/${service_point_id} {"data": {"type": "service-points","attributes": {"key": "initial-service-point-${random}","stores": ["DE"],"isActive": "false","name": "Updated Service Point"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] Updated Service Point
+ And Response body parameter should be: [data][attributes][key] initial-service-point-${random}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][stores] DE
+ [Teardown] Deactivate service point via BAPI ${service_point_id}
+
+Get_Service_Point_By_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "SP by id ${random}","key": "service-point-to-get${random}","isActive": "true","stores": ["AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][attributes][key] service_point_key_to_get
+ And Save value to a variable: [data][id] service_point_id_to_get
+ When I send a GET request: /service-points/${service_point_id_to_get}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${service_point_id_to_get}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] SP by id ${random}
+ And Response body parameter should be: [data][attributes][key] ${service_point_key_to_get}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be: [data][attributes][stores] AT
+ And Response body has correct self link internal
+ [Teardown] Deactivate service point via BAPI ${service_point_id_to_get}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/negative.robot
new file mode 100644
index 0000000..d4468a9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/negative.robot
@@ -0,0 +1,143 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Create_Service_Type_With_Maximum_Length_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "dsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374333asss"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5420
+ And Response should return error message: A service type key must have length from 1 to 255 characters.
+
+Create_Service_Type_With_256_Length_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "dsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374qe69ady78huijkndsfhkjndfjknjknfksdnfkjnsdjkfndskjfndsfjnsdkfnk2374333asss", "key": "service1-test${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5422
+ And Response should return error message: A service type name must have length from 1 to 255 characters.
+
+Create_Duplicate_Service_Type_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=with-duplicate-key name=Duplicate key key=with-duplicate-key
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Another Service 2 ${random}", "key": "with-duplicate-key"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5419
+ And Response should return error message: A service type with the same key already exists.
+ [Teardown] Delete service type in DB with-duplicate-key
+
+Create_Service_Type_With_Duplicate_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=with-duplicate-name${random} name=Duplicate Service key=with-duplicate-name${random}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Duplicate Service", "key": "another-key${random}"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5425
+ And Response should return error message: A service type with the same name already exists.
+ [Teardown] Delete service type in DB with-duplicate-name${random}
+
+Create_Service_Type_With_Empty_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Invalid Key Length", "key": ""}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5420
+ And Response should return error message: A service type key must have length from 1 to 255 characters.
+
+Create_Service_Type_With_Empty_Name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "", "key": "invalid-name-length"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5422
+ And Response should return error message: A service type name must have length from 1 to 255 characters.
+
+Create_Service_Type_without_Auth
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 403
+
+Create_Service_Type_with_incorrect_Auth
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer incorrect
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 401
+
+Update_Service_Type_Key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=update-service-type-key${random} name=update-service-type-key key=update-service-type-key${random}
+ When I send a PATCH request: /service-types/update-service-type-key${random} {"data": {"type": "service-types", "attributes": {"key": "new-key"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5423
+ And Response should return error message: The service type key is immutable.
+ [Teardown] Delete service type in DB update-service-type-key${random}
+
+Update_Not_Existing_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /service-types/not-existing-service-type {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name ${random}","key": "original-key${random}"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5418
+ And Response should return error message: The service type entity was not found.
+
+Update_Service_Type_with_incorrect_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ Create service type in DB uuid=serv-ty${random} name=New Service key=serv-ty${random}
+ When I send a PATCH request: /service-types/serv-ty${random} {"data": {"type": "incorrect-types", "attributes": {"name": "Updated Service", "key": "serv-ty${random}"}}}
+ Then Response status code should be: 400
+ [Teardown] Delete service type in DB serv-ty${random}
+
+Update_Service_Type_without_Auth
+ When Create service type in DB 12345678${random} test test
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer
+ When I send a PATCH request: /service-types/12345678${random} {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name","key": "12345678${random}"}}}
+ Then Response status code should be: 403
+ [Teardown] Delete service type in DB 12345678${random}
+
+Get_Service_Types_No_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /service-types
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+
+Get_Service_Types_Invalid_Auth
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer InvalidToken
+ When I send a GET request: /service-types
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_Service_Type_By_ID_No_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ Create service type in DB uuid=service-by-id${random} name=service-by-id key=service-by-id${random}
+ When I send a GET request: /service-types/service-by-id${random}
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+ [Teardown] Delete service type in DB service-by-id${random}
+
+Get_Service_Type_By_ID_invalid_Auth
+ I set Headers: Content-Type=${default_header_content_type}
+ Create service type in DB uuid=service-invalid${random} name=service-invalid key=service-invalid${random}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer InvalidToken
+ When I send a GET request: /service-types/service-invalid${random}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Delete service type in DB service-invalid${random}
+
+Get_Nonexistent_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /service-types/nonexistent_id
+ Then Response status code should be: 404
+ And Response should return error code: 5418
+ And Response should return error message: The service type entity was not found.
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/positive.robot
new file mode 100644
index 0000000..3a2620f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/service_types/positive.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_Service_Types_List
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "S_type${random}", "key": "s_type${random}"}}}
+ And Save value to a variable: [data][id] service_type_id
+ When I send a GET request: /service-types
+ Then Response status code should be: 200
+ And Array in response should contain property with value: [data] type service-types
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should be in: data[0][attributes][name] Pickup S_type${random} robot Service Visit
+ And Response body parameter should be in: data[1][attributes][name] Pickup S_type${random} robot Service Visit
+ And Response body parameter should be in: data[0][attributes][key] pickup s_type${random} robot on-site-service
+ And Response body parameter should be in: data[1][attributes][key] pickup s_type${random} robot on-site-service
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Create_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Test Service ${random}
+ And Response body parameter should be: [data][attributes][key] service1-test${random}
+ And Response body has correct self link for created entity: ${service_type_id}
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Update_Service_Type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "original-key${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ When I send a PATCH request: /service-types/${service_type_id} {"data": {"type": "service-types", "attributes": {"name": "Updated Service Name","key": "original-key${random}"}}}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Updated Service Name
+ And Response body parameter should be: [data][attributes][key] original-key${random}
+ [Teardown] Delete service type in DB ${service_type_id}
+
+Get_Service_Type_by_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Collect Service${random}", "key": "collect${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ When I send a GET request: /service-types/${service_type_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] service-types
+ And Response body parameter should be: [data][attributes][name] Collect Service${random}
+ And Response body parameter should be: [data][attributes][key] collect${random}
+ [Teardown] Delete service type in DB ${service_type_id}
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/services/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/services/negative.robot
new file mode 100644
index 0000000..cc62914
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/services/negative.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Create_Service_No_Auth
+ And Create service point in DB uuid=262feb9d-33a7${random} name=TestSP${random} key=sp11${random} isActive=true storeName=DE
+ Then Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType${random} key=sp11${random}
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random} ", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Service_Invalid_Auth
+ Create service point in DB uuid=262feb9d-33a7${random} name=TestSP1${random} key=sp11${random} isActive=true storeName=DE
+ Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType1${random} key=sp11${random}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "33a7-5c55-9b04${random}", "servicePointUuid": "262feb9d-33a7${random}", "isActive": "true", "key": "service-point-1-collect"}}}
+ Then Response status code should be: 401
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Service_By_ID__No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2${random} key=sp11${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2${random} key=sp11${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ And I send a GET request: /services/262feb1fd22067e${random}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Get_Nonexistent_Service
+ When I get access token by user credentials: ${zed_admin.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services/nonexistent_id
+ Then Response status code should be: 400
+ And Response should return error code: 5400
+ And Response should return error message: The service entity was not found.
+
+Get_Services_No_Auth
+ When Create service point in DB uuid=262feb9d-33a7${random} name=TestSP2a${random} key=sp11a${random} isActive=true storeName=DE
+ And Create service type in DB uuid=33a7-5c55-9b04${random} name=TestType2a${random} key=sp11a${random}
+ Then Create service in DB servicePointUuid=262feb9d-33a7${random} serviceTypeUuid=33a7-5c55-9b04${random} uuid=262feb1fd22067e${random} key=s1f${random} isActive=true
+ When I send a GET request: /services
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Delete service point in DB 262feb9d-33a7${random}
+ ... AND Delete service type in DB 33a7-5c55-9b04${random}
+
+Create_Duplicate_Service_Point_Service_Relation
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Points ${random}","key": "some-service-point-news-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ Create service type in DB uuid=36796774${random} name=TestTypeNewQ${random} key=test-key-goes-here${random}
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service2-point-1-collects${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${36796774${random}}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "new-key2${random}"}}}
+ When Response status code should be: 400
+ And Response should return error code: 5429
+ And Response should return error message: A service with defined relation of service point and service type already exists.
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${36796774${random}}
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/services/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/services/positive.robot
new file mode 100644
index 0000000..286e665
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/services/positive.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_Services_List
+ [Setup]
+ Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /services
+ Then Response status code should be: 200
+ And Array in response should contain property with value: [data] type services
+ And Response should contain the array larger than a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][1][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Response body parameter should be: data[0][attributes][isActive] True
+ And Response body parameter should be: data[1][attributes][isActive] True
+ And Response body parameter should be in: data[0][attributes][key] s1 s2 robot
+ And Response body parameter should be in: data[1][attributes][key] s1 s2 robot
+ And Response body has correct self link
+
+Create_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ And Response body has correct self link for created entity: ${service_id}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Update_Service
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service ${random}", "key": "service1-test${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collect${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ # #update a service
+ When I send a PATCH request: /services/${service_id} {"data": {"type": "services", "attributes": {"isActive": "false"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should be: [data][attributes][key] service-point-1-collect${random}
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
+
+Get_Service_By_ID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #create a service point
+ When I send a POST request: /service-points {"data": {"type": "service-points","attributes": {"name": "Some Service Point ${random}","key": "some-service-point-new1-${random}","isActive":"true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][attributes][key] service_point_key
+ And Save value to a variable: [data][id] service_point_id
+ # #create a service type
+ When I send a POST request: /service-types {"data": {"type": "service-types", "attributes": {"name": "Test Service1 ${random}", "key": "service1-test1${random}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] service_type_id
+ # #create a service
+ When I send a POST request: /services {"data": {"type": "services", "attributes": {"serviceTypeUuid": "${service_type_id}", "servicePointUuid": "${service_point_id}", "isActive":"true", "key": "service-point-1-collecta${random}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ Then Save value to a variable: [data][id] service_id
+ When I send a GET request: /services/${service_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][type] services
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should not be EMPTY: [data][attributes][uuid]
+ And Response body parameter should not be EMPTY: [data][id]
+ [Teardown] Run Keywords Delete service point in DB ${service_point_id}
+ ... AND Delete service type in DB ${service_type_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/bapi/service_points/teardown/service_points_teardown.robot b/atest/testdata/performance/tests/api/suite/bapi/service_points/teardown/service_points_teardown.robot
new file mode 100644
index 0000000..a8e6089
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/service_points/teardown/service_points_teardown.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office service-points shipment-service-points product-offer-service-points service-points-cart product-offer-service-points-availability marketplace-merchant-product-offer-service-points-availability shipment-product-offer-service-points-availability marketplace-merchant-portal-product-offer-service-points inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Delete_all_non-default_service_points_from_DB_with_p&s
+ Delete all non-default service points from DB with p&s
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/bapi/shipment_types/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/shipment_types/negative.robot
new file mode 100644
index 0000000..4dfea78
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/shipment_types/negative.robot
@@ -0,0 +1,148 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/shipment_type_steps.robot
+Test Tags bapi shipment spryker-core spryker-core-back-office marketplace-shipment
+
+*** Test Cases ***
+Create_shipment_type_with_incorrect_type_in_body
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5845
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "incorrect-type","attributes": {"name": "Some Shipment Type","key": "wrong-type${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 55020
+ And Response should return error message: Unknown error.
+
+Create_shipment_type_with_empty_body
+ [Documentation] https://spryker.atlassian.net/browse/FRW-5851
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {}
+ Then Response status code should be: 400
+ And Response should return error code: 55020
+ And Response should return error message: Unknown error.
+
+Create_shipment_type_with_empty_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer wrong_token
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "empty_token${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Create_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "incorrect_token${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Create_shipment_type_without_key_in_request
+ [Documentation] FRW-1597: Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Create_shipment_type_with_empty_key_in_request
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type ${random}","key": "","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5503
+ And Response should return error message: A delivery type key must have a length from 1 to 255 characters.
+
+Create_shipment_type_with_already_used_key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "existing-shipment-type-key","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type","key": "existing-shipment-type-key","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5502
+ And Response should return error message: A delivery type with the same key already exists.
+ [Teardown] Delete shipment type in DB: existing-shipment-type-key
+
+Update_shipment_type_without_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer wrong_token
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Update_shipment_type_without_key
+ [Documentation] FRW-1597: Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Update_shipment_type_with_empty_key
+ [Documentation] FRW-1597: Attribute validation in Glue Requests
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "name${random}","key": "","isActive": "true","stores": ["DE"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Update_shipment_type_with_not_existing_key
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a PATCH request: /shipment-types/not-existing-key
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Retrieve_single_shipment_type_without_auth
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer wrong_token
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Retrieve_single_shipment_type_with_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Retrieve_single_shipment_type_with_incorrect_id
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a GET request: /shipment-types/incorrect_id
+ Then Response status code should be: 404
+ And Response should return error code: 5501
+ And Response should return error message: A delivery type entity was not found.
+
+Retrieve_list_of_shipment_types_without_auth
+ [Setup] I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /shipment-types/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Retrieve_list_of_shipment_types_witt_incorrect_token
+ [Setup] I set Headers: Authorization=wrong_token
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
diff --git a/atest/testdata/performance/tests/api/suite/bapi/shipment_types/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/shipment_types/positive.robot
new file mode 100644
index 0000000..2b2e2f8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/shipment_types/positive.robot
@@ -0,0 +1,165 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/shipment_type_steps.robot
+Test Tags bapi shipment spryker-core spryker-core-back-office marketplace-shipment
+
+*** Test Cases ***
+Create_shipment_type
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "Some Shipment Type ${random}","key": "some-shipment-type-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] shipment-types
+ And Save value to a variable: [data][id] shipment_type_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] Some Shipment Type ${random}
+ And Response body parameter should be: [data][attributes][key] some-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link for created entity: ${shipment_type_id}
+ [Teardown] Delete shipment type in DB: some-shipment-type-${random}
+
+Create_new_shipment_type_with_existing_name
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "not_unique_name","key": "new-shipment-type-${random}","isActive": "true","stores": ["AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] new_shipment_type_uuid
+ # Create new shipment type with existing name
+ When I send a POST request: /shipment-types {"data": {"type": "shipment-types","attributes": {"name": "not_unique_name","key": "second-shipment-type-${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] shipment-types
+ And Save value to a variable: [data][id] shipment_type_id
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] not_unique_name
+ And Response body parameter should be: [data][attributes][key] second-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link for created entity: ${shipment_type_id}
+ # check that first shipment time still exist and not overrided
+ And I send a GET request: /shipment-types/
+ And I send a GET request: /shipment-types/${new_shipment_type_uuid}
+ And Response body parameter should be: [data][attributes][key] new-shipment-type-${random}
+ And Response body parameter should be: [data][attributes][name] not_unique_name
+ [Teardown] Run Keywords Delete shipment type in DB: new-shipment-type-${random}
+ ... AND Delete shipment type in DB: second-shipment-type-${random}
+
+Update_shipment_type_change_name_store_relation_and_deactivate
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "name${random}","key": "update-shipment-type-key${random}","isActive": "true","stores": ["DE"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] shipment_type_uuid
+ # Update the Delivery Type with new attributes via PATCH request
+ When I send a PATCH request: /shipment-types/${shipment_type_uuid}
+ ... {"data": {"type": "shipment-types","attributes": {"name": "updated_name${random}","isActive": "false","stores": ["AT"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ When I send a GET request: /shipment-types/${shipment_type_uuid}
+ And Response body parameter should be: [data][attributes][name] updated_name${random}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][stores] AT
+ And Response body has correct self link internal
+ [Teardown] Delete shipment type in DB: update-shipment-type-key${random}
+
+Retrieve_single_shipment_type_with_valid_token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type${random}","key": "shipment-key${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] delivery_type_uuid
+ When I send a GET request: /shipment-types/${delivery_type_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] shipment-types
+ And Response body parameter should be: [data][attributes][name] shipment-type${random}
+ And Response body parameter should be: [data][attributes][key] shipment-key${random}
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response body parameter should be in: [data][attributes][stores] DE AT
+ And Response body parameter should be in: [data][attributes][stores] AT DE
+ And Response body has correct self link internal
+ [Teardown] Delete shipment type in DB: shipment-key${random}
+
+Retrieve_list_of_shipment_types_with_valid_token_and_pagination
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "shipment-key1${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "shipment-key2${random}","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?page[offset]=0&page[limit]=2
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array in response should contain property with NOT EMPTY value: [data] id
+ And Each array element of array in response should contain property with value: [data] type shipment-types
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][name]
+ And Each array in response should contain property with NOT EMPTY value: [data] [attributes][key]
+ And Each array element of array in response should contain property with value in: [data] [attributes][isActive] True False
+ And Response should contain the array larger than a certain size: [data][0][attributes][stores] 0
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of the array in response should contain a nested array larger than a certain size: [data] [attributes][stores] 0
+ [Teardown] Run Keywords Delete shipment type in DB: shipment-key1${random}
+ ... AND Delete shipment type in DB: shipment-key2${random}
+
+Retrieve_list_of_shipment_types_with_filtering
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "shipment-key1${random}","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "shipment-key2${random}","isActive": "true","stores": ["AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type3${random}","key": "shipment-key3${random}","isActive": "true","stores": ["DE"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?filter[shipment-types.stores]=AT
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array in response should contain property with value NOT in: [data] [attributes][key] shipment-key3${random}
+ [Teardown] Run Keywords Delete shipment type in DB: shipment-key1${random}
+ ... AND Delete shipment type in DB: shipment-key2${random}
+ ... AND Delete shipment type in DB: shipment-key3${random}
+
+Retrieve_list_of_shipment_types_with_sorting_by_key_ASC
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "aaa_shipment-key1","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "www_shipment-key2","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?sort=key
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][attributes][key] aaa_shipment-key1
+ And Response body has correct self link
+ [Teardown] Run Keywords Delete shipment type in DB: aaa_shipment-key1
+ ... AND Delete shipment type in DB: www_shipment-key2
+
+Retrieve_list_of_shipment_types_with_sorting_by_key_DESC
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ #prepare test data
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type1${random}","key": "aaa_shipment-key1","isActive": "true","stores": ["DE", "AT"]}}}
+ When I send a POST request: /shipment-types
+ ... {"data": {"type": "shipment-types","attributes": {"name": "shipment-type2${random}","key": "www_shipment-key2","isActive": "true","stores": ["AT"]}}}
+ # run get request
+ When I send a GET request: /shipment-types?sort=-key
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][attributes][key] www_shipment-key2
+ And Response body has correct self link
+ [Teardown] Run Keywords Delete shipment type in DB: aaa_shipment-key1
+ ... AND Delete shipment type in DB: www_shipment-key2
diff --git a/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/negative.robot
new file mode 100644
index 0000000..3095dd6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/negative.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi spryker-core spryker-core-back-office warehouse-user-management
+
+*** Test Cases ***
+New_warehouse_token_without_autorization
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+
+New_warehouse_token_with_invalid_token
+ When I set Headers: Authorization=fake_token Content-Type=application/x-www-form-urlencoded
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+New_warehouse_token_for_admin_user_who_is_not_a_WH_user
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${admin_not_warehouse_user.email}","password": "${admin_not_warehouse_user.password}"}
+ Then Response status code should be: 200
+ And Save value to a variable: [access_token] bapi_token
+ When I set Headers: Authorization=Bearer ${bapi_token}
+ And I send a POST request: /warehouse-tokens {}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [0][code] 5101
+ And Response body parameter should be: [0][message] Operation is forbidden.
diff --git a/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/positive.robot
new file mode 100644
index 0000000..af06f3a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/warehouse_tokens/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Test Tags bapi spryker-core spryker-core-back-office warehouse-user-management
+
+*** Test Cases ***
+Generate_new_user_token
+ When I set Headers: Content-Type=application/x-www-form-urlencoded
+ When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+ Then Response status code should be: 200
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [token_type]
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+# Generate_new_warehouse_token
+# # needs to be completed as werahouse token can be created only for user who is a warehouse user with assigned and ACTIVE warehouse.
+# # Making user a warehouse user is available now only via Back office frontend.
+# When I set Headers: Content-Type=application/x-www-form-urlencoded
+# When I send a POST request: /token {"grantType": "${grant_type.password}","username": "${zed_admin.email}","password": "${zed_admin.password}"}
+# Then Response status code should be: 200
+# And Save value to a variable: [access_token] bapi_token
+# When I set Headers: Authorization=${bapi_token} Content-Type=application/x-www-form-urlencoded
+# And I send a POST request: /warehouse-tokens {}
+# Then Response status code should be: 201
+# And Response body parameter should be: [data][type] warehouse-tokens
+# And Response body parameter should be: [data][attributes] Bearer
+# And Response body parameter should be greater than: [data][attributes][expiresin] 0
+# And Response body parameter should be less than: [data][attributes][expiresin] 30000
+# And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+# And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+# And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+# And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/negative.robot b/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/negative.robot
new file mode 100644
index 0000000..92e57ce
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/negative.robot
@@ -0,0 +1,185 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office warehouse-user-management
+
+*** Test Cases ***
+Create_warehouse_user_assignment_with_invalid_token
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Create_warehouse_user_assignment_without_token
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 403
+ And Response should return error message: Unauthorized request.
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Create_warehouse_user_assignment_as_warehouse_user_for_other_user
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 404
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].admin_user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+
+Create_warehouse_user_assignment_with_invalid_body
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "test","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5202
+ And Response should return error message: User not found.
+
+Create_warehouse_user_assignment_with_incorrect_type
+ [Documentation] https://spryker.atlassian.net/browse/FRW-6312
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token by user credentials: ${zed_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "invalid", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ [Teardown] Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Create_warehouse_user_assignment_with_duplicate_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 5206
+ And Response should return error message: Warehouse user assignment already exists.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_warehouse_user_assignments_by_UUID_without_token
+ [Setup] Run Keywords Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ When I set Headers: Content-Type=${default_header_content_type}
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_user_assignments_by_UUID_with_invalid_token
+ And Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ And Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ When I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer wrong_token
+ Then I send a GET request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_user_assignments_by_invalid_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ Then I send a GET request: /warehouse-user-assignments/invalid
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_user_assignments_list_with_invalid_token
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer wrong_token
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_user_assignments_list_without_token
+ [Setup] Run Keywords Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ When I set Headers: Content-Type=${default_header_content_type}
+ Then I send a GET request: /warehouse-user-assignments/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Update_warehouse_user_assignment_without_token
+ [Setup] Run Keywords Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ When I set Headers: Content-Type=${default_header_content_type}
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Update_warehouse_user_assignment_with_invalid_token
+ [Setup] Run Keywords I get access token by user credentials: invalid
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ Then I send a PATCH request: /warehouse-user-assignments/${id_warehouse_user_assignment} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 403
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Update_warehouse_user_assignment_without_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid_2}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ Then I send a PATCH request: /warehouse-user-assignments/invalid {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 5201
+ And Response should return error message: Warehouse user assignment not found.
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 0
+
+Delete_warehouse_user_assignment_without_token
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 404
+ [Teardown] Run Keywords Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Delete_warehouse_user_assignment_with_invalid_token
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer invalid
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Create_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse[0].fk_warehouse_spryker} ${warehouse_user[0].user_uuid} false
+ Then Get_warehouse_user_assignment_id: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ Then I send a DELETE request: /warehouse-user-assignments/${id_warehouse_user_assignment}
+ Then Response status code should be: 401
+ And Remove_warehouse_user_assignment: ${warehouse[0].warehouse_uuid} ${warehouse_user[0].user_uuid}
+ And Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
diff --git a/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/positive.robot b/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/positive.robot
new file mode 100644
index 0000000..447de9b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/bapi/warehouse_user_assignments/positive.robot
@@ -0,0 +1,267 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../resources/common/common_api.robot
+Resource ../../../../../resources/steps/warehouse_user_assignment_steps.robot
+Test Tags bapi spryker-core spryker-core-back-office warehouse-user-management
+
+*** Test Cases ***
+Assign_user_to_warehouse
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response reason should be: Created
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link for created entity: ${warehouse_assignment_id}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Assign_user_to_warehouse_with_include
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ And Response body parameter should not be EMPTY: [data][relationships][users][data][0][id]
+ And Each array in response should contain property with NOT EMPTY value: [data][relationships][users][data] id
+ And Each array element of array in response should contain property with value: [data][relationships][users][data] type users
+ And Each array in response should contain property with NOT EMPTY value: [included] id
+ And Each array element of array in response should contain property with value: [included] type users
+ And Response body parameter should be: [included][0][attributes][username] ${warehouse_user[0].user_name}
+ And Response body parameter should be: [included][0][attributes][firstName] ${warehouse_user[0].user_first_name}
+ And Response body parameter should be: [included][0][attributes][lastName] ${warehouse_user[0].user_last_name}
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_warehouse_user_assignments_by_UUID
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # assign several warehouses to one user [only one warehouse active]
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][type] warehouse-user-assignments
+ And Response body parameter should not be EMPTY: [data][attributes][userUuid]
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body parameter should be: [data][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should not be EMPTY: [data][attributes][warehouse][uuid]
+ And Response body parameter should be: [data][attributes][warehouse][isActive] True
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_warehouse_user_assignments_list
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ # assign several warehouses to one user [only one warehouse active]
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should be in: [data][0][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be in: [data][1][id] ${warehouse_assignment_id_1} ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][1][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].user_uuid}
+ And Response body parameter should be: [data][1][attributes][userUuid] ${warehouse_user[0].user_uuid}
+ And Response body parameter should be in: [data][0][attributes][isActive] False True
+ And Response body parameter should be in: [data][1][attributes][isActive] False True
+ And Response body parameter should be in: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name} ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be in: [data][1][attributes][warehouse][name] ${warehouse[0].warehouse_name} ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ And Response body parameter should be: [data][1][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_assignment_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid_2}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.uuid]=${warehouse_assignment_id_1}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][type] warehouse-user-assignments
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 0
+
+Get_warehouse_user_assignments_with_filter_by_warehouse_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid_2}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.warehouseUuid]=${warehouse[0].video_king_warehouse_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].user_uuid_2}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 0
+
+Get_warehouse_user_assignments_with_filter_by_user_uuid
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid_2}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.userUuid]=${warehouse_user[0].user_uuid}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_1}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].user_uuid}
+ And Response body parameter should be: [data][0][attributes][isActive] False
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 0
+
+Get_warehouse_user_assignments_with_filter_by_isActive
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid_2}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/?filter[warehouse-user-assignments.isActive]=true
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][id] ${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][0][attributes][userUuid] ${warehouse_user[0].user_uuid_2}
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][warehouse][name] ${warehouse[0].video_king_warehouse_name}
+ And Response body parameter should be: [data][0][attributes][warehouse][uuid] ${warehouse[0].video_king_warehouse_uuid}
+ And Response body parameter should be: [data][0][attributes][warehouse][isActive] True
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid_2} 0
+
+Update_warehouse_user_assignment
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][id] ${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id} {"data":{"attributes":{"isActive":"false"}}}
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+
+Create_warehouse_user_assignment_with_multiple_active_assignments
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] True
+ When I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] True
+ # when we creating second active user warehouse assignment for one user,the existing one assignment deactivated
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
+
+Update_one_of_already exist_warehouse_user_assignment_with_two_assignments_to active
+ [Setup] Run Keywords I get access token by user credentials: ${zed_admin.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid}"},"isActive":"false"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_1
+ When I send a POST request: /warehouse-user-assignments?include=users {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].user_uuid}","warehouse" :{"uuid": "${warehouse[0].video_king_warehouse_uuid}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id_2
+ Then I send a PATCH request: /warehouse-user-assignments/${warehouse_assignment_id_1} {"data":{"attributes":{"isActive":"true"}}}
+ Then Response status code should be: 200
+ Then I send a GET request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ And Response body parameter should be: [data][attributes][isActive] False
+ [Teardown] Run Keywords I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_1}
+ ... AND Response status code should be: 204
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].user_uuid} 0
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id_2}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/suite/dynamic_store/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/suite/dynamic_store/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..2317ec1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/dynamic_store/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core spryker-core-back-office marketplace-merchantportal-core
+
+*** Test Cases ***
+Search_by_abstract_sku_per_store
+ [Tags] dms-on
+ When I set Headers: store=DE
+ Then I send a GET request: /catalog-search?q=${concrete_product_with_alternative.abstract_sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${concrete_product_with_alternative.price_de}
+ When I set Headers: store=AT
+ Then I send a GET request: /catalog-search?q=${concrete_product_with_alternative.abstract_sku}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be either: [data][0][attributes][abstractProducts][0][prices][0][DEFAULT] [data][0][attributes][abstractProducts][0][prices][1][DEFAULT] ${concrete_product_with_alternative.price_at}
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
new file mode 100644
index 0000000..938a862
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/negative.robot
@@ -0,0 +1,26 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Get_alternative_abstract_with_nonexistant_SKU
+ When I send a GET request: /concrete-products/fake/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_alternative_abstract_with_abstract_SKU
+ When I send a GET request: /concrete-products/${product_with_alternative.abstract_sku}/abstract-alternative-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+Get_alternative_abstract_without_SKU
+ When I send a GET request: /concrete-products//abstract-alternative-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
new file mode 100644
index 0000000..dd6d2b4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_alternative_products/positive.robot
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product alternative-products
+
+*** Test Cases ***
+Product_has_abstract_alternative
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}/abstract-alternative-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body parameter should have datatype: [data][0][attributes][name] str
+ And Response body parameter should be: [data][0][attributes][sku] ${alternative_abstract_product.sku}
+ And Response body has correct self link
+
+Product_has_abstract_alternative_with_includes
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}/abstract-alternative-products?include=abstract-product-image-sets,abstract-product-availabilities,abstract-product-prices,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] abstract-products
+ And Response body has correct self link
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: abstract-product-prices
+
+Product_has_no_abstract_alternative
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/abstract-alternative-products
+ Then Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ And Response reason should be: OK
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
new file mode 100644
index 0000000..113910f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_abstract_availability_by_concrete_SKU
+ When I send a GET request: /abstract-products/${product_with_alternative.concrete_sku}/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 305
+ And Response should return error message: Availability is not found.
+
+Get_abstract_availability_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
new file mode 100644
index 0000000..8d1debe
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_availabilities/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Product_is_available_with_stock_and_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock_2}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock_2}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_with_stock
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body has correct self link
+
+Product_is_available_never_out_of_stock
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_unavailable
+ When I send a GET request: /abstract-products/${product_availability.abstract_unavailable_product}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_unavailable_product}
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
+
+Product_is_available_with_3_concrete_stocks_combined
+ #checks that stock of all 3 concretes as aggregated in response
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}/abstract-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] abstract-product-availabilities
+ And Response body parameter should be: [data][0][id] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] ${stock_is_20}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
new file mode 100644
index 0000000..3431226
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_image_sets_by_concrete_SKU
+ When I send a GET request: /abstract-products/${product_with_alternative.concrete_sku}/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 303
+ And Response should return error message: Can`t find abstract product image sets.
+
+Get_abstract_image_sets_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
new file mode 100644
index 0000000..40e434b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_image_sets/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Abstract_image_sets_with_1_concrete
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_with_stock_and_never_out_of_stock}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
+
+Abstract_image_sets_with_3_concretes
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}/abstract-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product_with_variants.concretes_3}
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/negative.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
new file mode 100644
index 0000000..640424d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Get_abstract_prices_by_concrete_SKU
+ When I send a GET request: /abstract-products/${product_with_alternative.concrete_sku}/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_by_fake_SKU
+ When I send a GET request: /abstract-products/fake/abstract-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 307
+ And Response should return error message: Can`t find abstract product prices.
+
+Get_abstract_prices_with_missing_SKU
+ When I send a GET request: /abstract-products//abstract-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/positive.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
new file mode 100644
index 0000000..8ee0000
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_product_prices/positive.robot
@@ -0,0 +1,87 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product prices
+
+*** Test Cases ***
+Abstract_prices_detault_only
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+Abstract_prices_detault_only_CHF
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}/abstract-product-prices?currency=CHF&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body has correct self link
+
+
+Abstract_volume_prices
+ When I send a GET request: /abstract-products/${abstract_product.product_with_volume_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_volume_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 1
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][grossAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][netAmount] 1
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][volumePrices][0][quantity] 1
+ And Response body has correct self link
+
+Abstract_prices_original_price
+ When I send a GET request: /abstract-products/${abstract_product.product_with_original_prices.sku}/abstract-product-prices?currency=EUR&priceMode=GROSS_MODE
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${abstract_product.product_with_original_prices.sku}
+ And Response body parameter should be greater than: [data][0][attributes][price] 100
+ And Save value to a variable: [data][0][attributes][price] default_price
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] ${default_price}
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should be greater than: [data][0][attributes][prices][1][grossAmount] ${default_price}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.code}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.name}
+ And Each array element of array in response should contain value: [data][0][attributes][prices] ${currency.eur.symbol}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${arrow}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/negative.robot
new file mode 100644
index 0000000..0366e8b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_abstract_product_by_concrete_SKU
+ When I send a GET request: /abstract-products/${product_with_alternative.concrete_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_by_fake_SKU
+ When I send a GET request: /abstract-products/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_abstract_product_with_missing_SKU
+ When I send a GET request: /abstract-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/positive.robot
new file mode 100644
index 0000000..bcb0fd8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/abstract_product_endpoints/abstract_products/positive.robot
@@ -0,0 +1,180 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product tax product-labels product-options inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Abstract_product_with_one_concrete
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][merchantReference] None
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 1
+ And Each array element of array in response should contain value: [data][attributes][attributeMap][product_concrete_ids] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should contain: [data][attributes][superAttributes] ${abstract_available_product_with_stock.superattribute}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_3_concrete3
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][attributes][merchantReference] None
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body parameter should be: [data][attributes][name] ${abstract_product_with_variants.concretes_name_3}
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][attributes][attributeMap] 4
+ And Response should contain the array of a certain size: [data][attributes][attributeMap][product_concrete_ids] 3
+ And Each array element of array in response should contain value: [data][attributes][attributeMap][product_concrete_ids] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should contain: [data][attributes][superAttributes] ${abstract_product_with_variants.concretes_superattribute_3}
+ And Response body parameter should not be EMPTY: [data][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body has correct self link internal
+
+Abstract_product_with_abstract_includes_for_availability_images_taxes_categories_and_prices
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}?include=abstract-product-availabilities,abstract-product-image-sets,product-tax-sets,category-nodes,abstract-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][category-nodes][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][abstract-product-prices][data] 0
+ And Response should contain the array larger than a certain size: [included] 4
+ And Response include should contain certain entity type: category-nodes
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include element has self link: category-nodes
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: abstract-product-prices
+
+
+Abstract_product_with_abstract_includes_for_labels
+ [Setup] Trigger product labels update
+ When I send a GET request: /abstract-products/${abstract_product.product_with_label.sku}?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_label.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_label.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_label.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-labels][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+Abstract_product_with_abstract_includes_for_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_reviews.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_reviews.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_reviews.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-reviews][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-reviews
+ And Response include element has self link: product-reviews
+
+Abstract_product_with_abstract_includes_for_options
+ When I send a GET request: /abstract-products/${abstract_product.product_with_options.sku}?include=product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_options.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_options.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_options.name}
+ And Response body has correct self link internal
+ And Response should contain the array larger than a certain size: [data][relationships][product-options][data] 0
+ And Response should contain the array larger than a certain size: [included] 1
+ And Response include should contain certain entity type: product-options
+ And Response include element has self link: product-options
+
+Abstract_product_with_3_concrete_and_concrete_nested_includes
+ When I send a GET request: /abstract-products/${abstract_product_with_variants.concretes_3}?include=concrete-products,concrete-product-prices,concrete-product-image-sets,concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product_with_variants.concretes_3}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product_with_variants.concretes_name_3}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 3
+ And Response should contain the array larger than a certain size: [included] 5
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include element has self link: concrete-products
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+
+Abstract_product_with_concrete_includes_nested_offers
+ When I send a GET request: /abstract-products/${abstract_product.product_with_concrete_offers.sku}?include=concrete-products,product-offers,merchants,product-offer-availabilities,product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product.product_with_concrete_offers.sku}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product.product_with_concrete_offers.sku}
+ And Response body parameter should be: [data][attributes][name] ${abstract_product.product_with_concrete_offers.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] ${abstract_product.product_with_concrete_offers.concretes_count}
+ And Response should contain the array larger than a certain size: [included] 9
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offers
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: concrete-products
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offers
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+
+Abstract_product_in_different_locales_languages
+ When I set Headers: Accept-Language=de-DE
+ And I send a GET request: /abstract-products/${abstract_product.product_with_label.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_with_label.description_de}
+ When I set Headers: Accept-Language=en-US
+ And I send a GET request: /abstract-products/${abstract_product.product_with_label.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][attributes][description] ${abstract_product.product_with_label.description_en}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/negative.robot
new file mode 100644
index 0000000..fa7e3d5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/negative.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_acess_token_with_invalid_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":"fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_invalid_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"fake@spryker.com","password":"${yves_user.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+
+Get_acess_token_with_empty_password
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_second_user.email}","password":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+
+Get_acess_token_with_empty_email
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: username => This value should not be blank.
+
+Get_acess_token_with_invalid_type
+ When I send a POST request: /access-tokens {"data":{"type":"access","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_acess_token_with_empty_type
+ When I send a POST request: /access-tokens {"data":{"type":"","attributes":{"username":"${yves_second_user.email}","password":"${yves_second_user.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/positive.robot
new file mode 100644
index 0000000..d09f0eb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/access_tokens/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_access_token_for_customer
+ When I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body should contain: idCompanyUser
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/negative.robot
new file mode 100644
index 0000000..77bcdb7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/negative.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+#######POST#######
+Refresh_token_with_access_token
+ [Setup] I get access token for the customer: ${yves_user.email}
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_invalid_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "faketoken"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 004
+ And Response should return error message: Failed to refresh token.
+
+Refresh_token_with_empty_refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": ""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: refreshToken => This value should not be blank.
+
+Refresh_token_with_invalid_type
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "access-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Refresh_token_with_deleted_refresh_token
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ ... AND I set Headers: Authorization=Bearer ${access_token}
+ ... AND I send a DELETE request: /refresh-tokens/${refresh_token}
+ ... AND Response status code should be: 204
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Failed to refresh token.
+
+#######DELETE#######
+# Spryker is designed so removing non-existent refresh token will return 204 for security reasons
+Delete_refresh_token_with_invalid_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /refresh-tokens/faketoken
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_refresh_token_with_missing_refresh_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_refresh_token_with_no_access_token
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+# Spryker is designed so that deleting will return 204, but the token will not be removed and can be used (done for security reasons)
+Delete_refresh_token_for_another_user
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Authorization=${token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I set Headers: Authorization=Bearer ${access_token}
+ And I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/positive.robot
new file mode 100644
index 0000000..c519c34
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/refresh_tokens/positive.robot
@@ -0,0 +1,37 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Refresh_access_token_for_customer
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ When I send a POST request: /refresh-tokens {"data": {"type": "refresh-tokens","attributes": {"refreshToken": "${refresh_token}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Save value to a variable: [data][attributes][accessToken] refreshed_access_token
+ And Response body has correct self link internal
+ When I set Headers: Authorization=Bearer ${refreshed_access_token}
+ And I send a GET request: /customers
+ Then Response status code should be: 200
+
+Delete_refresh_token_for_customer
+ [Tags] skip-due-to-issue
+ [Documentation] Bug: https://spryker.atlassian.net/browse/FRW-10160
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_user.email}","password":"${yves_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][refreshToken] refresh_token
+ ... AND Save value to a variable: [data][attributes][accessToken] access_token
+ When I set Headers: Authorization=Bearer ${access_token}
+ And I send a DELETE request: /refresh-tokens/${refresh_token}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/negative.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/negative.robot
new file mode 100644
index 0000000..efd06e1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/negative.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer_with_invalid_client_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "invalid_client_type","username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_missing_grant_type
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"username": "${yves_user.email}","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_for_customer_with_invalid_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "wrong_password"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_password
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_for_customer_with_invalid_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "fake@spryker.com","password": "${yves_user.password}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The user credentials were incorrect.
+
+
+Get_token_for_customer_with_missing_email
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ Then I send a POST request with data: /token {"grant_type": "${grant_type.password}","password": "${yves_user.password}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+
+Get_token_using_refresh_token_for_customer_with_missing_grant_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_client_type
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "invalid_client_type","refresh_token": "${refresh_token}"}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_grant
+ And Response body parameter should be: [error_description] The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
+
+
+Get_token_using_refresh_token_for_customer_with_missing_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
+
+
+Get_token_using_refresh_token_for_customer_with_invalid_refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "invalid_refresh_token"}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response body parameter should be: [error] invalid_request
+ And Response body parameter should be: [error_description] The refresh token is invalid.
diff --git a/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/positive.robot b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/positive.robot
new file mode 100644
index 0000000..5926b5e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/access_token_endpoints/token/positive.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl
+
+*** Test Cases ***
+Get_token_for_customer
+ I set Headers: Content-Type=${urlencoded_header_content_type}
+ I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ Response status code should be: 200
+ Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
+
+Get_token_using_refresh_token_for_customer
+ [Setup] Run Keywords I set Headers: Content-Type=${urlencoded_header_content_type}
+ ... AND I send a POST request with data: /token {"grant_type": "${grant_type.password}","username": "${yves_user.email}","password": "${yves_user.password}"}
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [refresh_token] refresh_token
+ When I set Headers: Content-Type=${urlencoded_header_content_type}
+ And I send a POST request with data: /token {"grant_type": "${grant_type.refresh_token}","refresh_token": "${refresh_token}"}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [token_type] Bearer
+ And Response body parameter should be greater than: [expires_in] 0
+ And Response body parameter should be less than: [expires_in] 30000
+ And Response body parameter should not be EMPTY: [access_token]
+ And Response body parameter should not be EMPTY: [refresh_token]
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/negative.robot
new file mode 100644
index 0000000..57bef12
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/negative.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Get_agent_token_for_user_who_is_not_agent
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${zed_admin.email}","password": "${zed_admin.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_invalid_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_non-existent_email
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "fake@spryker.com","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_email
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": "${agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_token_with_wrong_type
+ When I send a POST request: /agent-access-tokens {"data": {"type": "access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Get_agent_access_token_by_empty_email_and_empty_password
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "","password": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+Get_agent_access_token_with_blank_spaces
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+
+Get_agent_access_token_by_non_existent_user
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "spryker1232@gmail.com","password": "1234"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/positive.robot
new file mode 100644
index 0000000..681d6b5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_access_tokens/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_access_token
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
new file mode 100644
index 0000000..76c3ae6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/negative.robot
@@ -0,0 +1,73 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_cannot_impersonate_customer_with_no_agent_token
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_wrong_token_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_cannot_impersonate_customer_with_invalid_token
+ [Setup] I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer fake
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Agent_cannot_impersonate_customer_with_wrong_type
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-token","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Agent_cannot_impersonate_customer_with_invalid_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "fake"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_empty_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": ""}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
+
+Agent_cannot_impersonate_customer_with_missing_customer_reference
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4104
+ And Response should return error message: Failed to impersonate a customer.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
new file mode 100644
index 0000000..ffa309a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_impersonation_access_tokens/positive.robot
@@ -0,0 +1,44 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist
+
+*** Test Cases ***
+Agent_can_get_customer_impersonation_token
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [data][type] agent-customer-impersonation-access-tokens
+ And Response body parameter should be: [data][attributes][tokenType] Bearer
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 25000
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
+
+Customer_impersonation_token_can_be_used
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ ... AND I send a POST request: /agent-customer-impersonation-access-tokens {"data": {"type": "agent-customer-impersonation-access-tokens","attributes":{"customerReference": "${yves_user.reference}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] impersonation_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${impersonation_token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"name": "cart${random}","priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] cart_uid
+ And I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete.product_1_sku}","quantity": 1}}}
+ And Response status code should be: 201
+ When I get access token for the customer: ${yves_user.email}
+ And I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ Then I send a GET request: /carts/${cart_uid}?include=items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][id] ${cart_uid}
+ And Response body parameter should be: [included][0][attributes][sku] ${bundle_product.concrete.product_1_sku}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/negative.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/negative.robot
new file mode 100644
index 0000000..935a8eb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/negative.robot
@@ -0,0 +1,35 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core customer-access acl agent-assist
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Not_agent_can't_get_search_for_customers
+ When I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${non_agent.email}","password": "${non_agent.password}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4101
+ And Response should return error message: Failed to authenticate an agent.
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+
+Agent_can't_get_search_for_customers_without_token
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
+
+Agent_searches_for_customers_with_customer_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 4103
+ And Response should return error message: Action is available to agent user only.
diff --git a/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/positive.robot b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/positive.robot
new file mode 100644
index 0000000..f6a8da9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/agent_endpoints/agent_customer_search/positive.robot
@@ -0,0 +1,170 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core customer-access acl agent-assist customer-account-management
+
+*** Test Cases ***
+Agent_can_get_search_for_customers_without_search_parameters
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 10
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_email
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_user.email}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--21
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] sonia@spryker.com
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Sonia
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Wagner
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_first_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_second_user.first_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--4
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] bill.martin@spryker.co
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Bill
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Martin
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_last_name
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=${yves_second_user.last_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 1
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Response body parameter should contain: [data][0][attributes][customers][0][customerReference] DE--4
+ And Response body parameter should contain: [data][0][attributes][customers][0][email] bill.martin@spryker.co
+ And Response body parameter should contain: [data][0][attributes][customers][0][firstName] Bill
+ And Response body parameter should contain: [data][0][attributes][customers][0][lastName] Martin
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_with_changed_page_limit
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=0&page[limit]=20
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 20
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+
+Agent_can_get_search_for_customers_by_substring
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=mar
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 2
+ And Response should contain the array of a certain size: [data][0][attributes][customers][0] 4
+ And Each array element of array in response should contain property: [data][0][attributes][customers] customerReference
+ And Each array element of array in response should contain property: [data][0][attributes][customers] email
+ And Each array element of array in response should contain property: [data][0][attributes][customers] firstName
+ And Each array element of array in response should contain property: [data][0][attributes][customers] lastName
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][customerReference]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][email]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][firstName]
+ And Response body parameter should not be EMPTY: [data][0][attributes][customers][0][lastName]
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] DE--2
+ And Response body parameter should be: [data][0][attributes][customers][0][email] maria.williams@spryker.com
+ And Response body parameter should be: [data][0][attributes][customers][1][customerReference] DE--4
+ And Response body parameter should be: [data][0][attributes][customers][1][email] bill.martin@spryker.com
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_by_incorrect_keyword
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?q=qqqq
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 0
+ And Response body has correct self link
+
+Agent_can_get_search_for_customers_from_last_page
+ [Setup] Run Keywords I send a POST request: /agent-access-tokens {"data": {"type": "agent-access-tokens","attributes": {"username": "${agent.email}","password": "${agent.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] agent_token
+ ... AND I Set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${agent_token}
+ When I send a GET request: /agent-customer-search?page[offset]=30&page[limit]=10
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][type] agent-customer-search
+ And Response should contain the array of a certain size: [data][0][attributes][customers] 6
+ And Response body parameter should be: [data][0][attributes][customers][0][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][customers][0][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][customers][0][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][customers][0][lastName] ${yves_user.last_name}
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][self]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/negative.robot b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/negative.robot
new file mode 100644
index 0000000..ed77dc8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/negative.robot
@@ -0,0 +1,131 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_without_customerId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/availability-notifications
+ Then Response status code should be: 404
+ # And Response reason should be: Forbidden
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_with_invalid_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=325tr
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Authorization=
+ ... AND I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_availability_notifications_without_access_token
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ ... AND I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#POST requests
+Subscribe_to_availability_notifications_with_empty_type
+ When I send a POST request: /availability-notifications {"data": {"type": "","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Subscribe_to_availability_notifications_without_type
+ When I send a POST request: /availability-notifications {"data": {"attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Subscribe_to_availability_notifications_with_invalid_sku
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "fake","email": "${yves_user.email}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Each array element of array in response should contain property with value: [errors] code 4601
+ And Each array element of array in response should contain property with value: [errors] status ${404}
+ And Array in response should contain property with value: [errors] detail Product not found.
+
+Subscribe_to_availability_notifications_with_invalid_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "gmail"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail email => This value is not a valid email address.
+
+Subscribe_to_availability_notifications_with_empty_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "","email": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+
+Subscribe_to_availability_notifications_without_sku_and_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+
+Subscribe_to_availability_notifications_with_existing_subscription
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4602
+ And Response should return error message: Subscription already exists.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_with_invalid_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/7fc6ebf
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4603
+ And Response should return error message: "Subscription doesnt exist."
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Delete_availability_notifications_without_availability_notification_id
+ [Setup] Run Keywords I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/positive.robot b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/positive.robot
new file mode 100644
index 0000000..6523137
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/availability_notifications/positive.robot
@@ -0,0 +1,78 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+#GET requests
+Get_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Get_empty_list_of_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+#POST requests
+Subscribe_to_availability_notifications_for_customer
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+Subscribe_to_availability_notifications_with_non_existing_email
+ When I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "sonia+${random}@spryker.com"}}}
+ And Save value to a variable: [data][id] availability_notification_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] availability-notifications
+ And Response body parameter should be: [data][id] ${availability_notification_id}
+ And Response body parameter should not be EMPTY: [data][attributes][localeName]
+ And Response body parameter should be: [data][attributes][email] sonia+${random}@spryker.com
+ And Response body parameter should be: [data][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Response body has correct self link for created entity: ${availability_notification_id}
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
+
+#DELETE requests
+Delete_availability_notifications_for_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a DELETE request: /availability-notifications/${availability_notification_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/negative.robot b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/negative.robot
new file mode 100644
index 0000000..f081c15
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Retrieves_my_availability_notifications_with_missing_auth_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Retrieves_my_availability_notifications_with_invalid_auth_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/positive.robot b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/positive.robot
new file mode 100644
index 0000000..0a2fe53
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/availability_endpoints/my_availability_notifications/positive.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue availability-notification spryker-core mailing-notifications customer-access acl inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+Get_my_availability_notifications
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /availability-notifications {"data": {"type": "availability-notifications","attributes": {"sku": "${product_with_alternative.concrete_sku}","email": "${yves_user.email}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] availability_notification_id
+ When I send a GET request: /my-availability-notifications
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] availability-notifications
+ And Response body parameter should be: [data][0][id] ${availability_notification_id}
+ And Response body parameter should be in: [data][0][attributes][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] localeName
+ And Each array element of array in response should contain nested property: [data] [attributes] email
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /availability-notifications/${availability_notification_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/negative.robot
new file mode 100644
index 0000000..9ae3279
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/negative.robot
@@ -0,0 +1,31 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_bundled_products_with_nonexisting_concrete_sku
+ [Documentation] bug: https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/fake/bundled-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_bundled_products_with_invalid_concrete_sku
+ [Documentation] bug: https://spryker.atlassian.net/browse/CC-15994
+ [Tags] skip-due-to-issue
+ When I send a GET request: /concrete-products/:sku/bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_bundled_products_with_missing_concrete_sku
+ When I send a GET request: /concrete-products//bundled-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/positive.robot
new file mode 100644
index 0000000..0cea688
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/bundle_endpoints/bundled_products/positive.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product-bundles product
+
+*** Test Cases ***
+Get_concrete_bundled_products_inside_concrete_bundle
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Response body parameter should be in: [data][0][attributes][sku] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][quantity] ${bundle_product.qty_of_each_product_inside_bundle}
+ And Response body has correct self link
+
+Get_concrete_bundled_products_inside_concrete_bundle_with_included_concretes
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}/bundled-products?include=concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value: [data] type bundled-products
+ And Response body has correct self link
+ And Each array element of array in response should contain nested property with value: [data] [relationships][concrete-products][data][0][type] concrete-products
+ And Response should contain the array of a certain size: [included] ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+
+Get_concrete_bundle_product_with_bundled_products_include
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.bundle_product_product_name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] Yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] ${bundle_product.qty_of_products_in_bundle}
+ And Each array element of array in response should contain property with value: [data][relationships][bundled-products][data] type bundled-products
+ And Response should contain the array larger than a certain size: [included] ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_abstract_bundle_product_with_bundled_products_include
+ When I send a GET request: /abstract-products/${bundle_product.abstract.sku}?include=bundled-products,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] abstract-products
+ And Response body parameter should be: [data][id] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.abstract.sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.bundle_product_product_name}
+ And Response body parameter should be: [data][attributes][attributes][bundled_product] Yes
+ And Response body parameter should be: [data][attributes][attributeNames][bundled_product] Bundled Product
+ And Response body parameter should be: [data][attributes][attributeMap][product_concrete_ids] ${bundle_product.concrete.product_4_sku}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][concrete-products][data] 1
+ And Response body parameter should be: [data][relationships][concrete-products][data][0][id] ${bundle_product.concrete.product_4_sku}
+ And Response should contain the array larger than a certain size: [included] ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: bundled-products
+
+Get_bundled_product_with_concrete_products_abstract_products_include
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}/bundled-products?include=concrete-products,abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${bundle_product.qty_of_products_in_bundle}
+ And Response body parameter should be in: [data][0][attributes][sku] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] ${bundle_product.qty_of_products_in_bundle}
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+
+Get_concrete_bundled_products_for_nonbundle_product
+ When I send a GET request: /concrete-products/${concrete.available_product.with_stock_and_never_out_of_stock.sku}/bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/negative.robot
new file mode 100644
index 0000000..826bfbf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/negative.robot
@@ -0,0 +1,70 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue cart spryker-core customer-access acl promotions-discounts marketplace-promotions-discounts gift-cards
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Create_git_card_code_with_invalid_access_token
+ [Setup] Run Keyword I set Headers: Authorization=345A9
+ When I send a POST request: /carts/cart_id/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "${random}"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Create_git_card_code_without_access_token
+ When I send a POST request: /carts/cart_id/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "${random}"}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Create_git_card_code_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/123/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "${random}"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Adding_eur_gift_cart_code_in_chf_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.chf.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "${random}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Adding_invalid_cart_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "123"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Gift_card_fully_used
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Create giftcode in Database: used_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_available_product.with_label}","quantity": 3}}}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "used_${random}"}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_available_product.with_label}"]}}}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_available_product.with_label}","quantity": 1}}}
+ When I send a POST request: /carts/${cart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "used_${random}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/positive.robot
new file mode 100644
index 0000000..ef6c32e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_codes/positive.robot
@@ -0,0 +1,145 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue cart gift-cards spryker-core customer-access acl promotions-discounts marketplace-promotions-discounts prices
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Add_gift_card_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Create giftcode in Database: normal_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_available_product.with_label}","quantity": 1}}}
+ When I send a POST request: /carts/${cart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "normal_${random}"}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] GROSS_MODE
+ And Response body parameter should be: [data][attributes][currency] EUR
+ And Response body parameter should be: [data][attributes][store] DE
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should not be EMPTY: [data][attributes][thresholds][0][type]
+ And Response body parameter should not be EMPTY: [data][attributes][thresholds][0][threshold]
+ And Response body parameter should not be EMPTY: [data][attributes][thresholds][0][fee]
+ And Response body parameter should not be EMPTY: [data][attributes][thresholds][0][deltaWithSubtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][thresholds][0][message]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response include should contain certain entity type: gift-cards
+ And Response include element has self link: gift-cards
+ And Response body parameter should be: [data][relationships][gift-cards] [data][0][type] gift-cards
+ And Response body parameter should not be EMPTY: [data][relationships][gift-cards][data][0][id]
+ And Response body parameter should be: [included][0][type] gift-cards
+ And Response body parameter should not be EMPTY: [included][0][id]
+ And Response body parameter should not be EMPTY: [included][0][attributes][code]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should be: [included][0][attributes][value] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] EUR
+ And Response body parameter should be: [included][0][attributes][actualValue] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][isActive] True
+ And Response include should contain certain entity type: gift-cards
+ And Response include element has self link: gift-cards
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Delete_gift_card_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Create giftcode in Database: delete_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_available_product.with_label}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "delete_${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][id] cart_code_id
+ When I send a DELETE request: /carts/${cart_id}/cart-codes/${cart_code_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Add_gift_card_code_to_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_label} 1
+ ... AND Save value to a variable: [data][id] guestcart_id
+ ... AND Create giftcode in Database: guest_${random} ${gift_card.amount}
+ When I send a POST request: /guest-carts/${guestcart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "guest_${random}"}}}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] GROSS_MODE
+ And Response body parameter should be: [data][attributes][currency] EUR
+ And Response body parameter should be: [data][attributes][store] DE
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be: [data][relationships][gift-cards] [data][0][type] gift-cards
+ And Response body parameter should not be EMPTY: [data][relationships][gift-cards][data][0][id]
+ And Response include should contain certain entity type: gift-cards
+ And Response include element has self link: gift-cards
+ And Response body parameter should not be EMPTY: [included][0][attributes][code]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should be: [included][0][attributes][value] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] EUR
+ And Response body parameter should be: [included][0][attributes][actualValue] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][isActive] True
+ And Response include should contain certain entity type: gift-cards
+ And Response include element has self link: gift-cards
+
+Delete_gift_card_code_from_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_label} 1
+ ... AND Save value to a variable: [data][id] guestcart_id
+ ... AND Create giftcode in Database: delete_guest_${random} ${gift_card.amount}
+ ... AND I send a POST request: /guest-carts/${guestcart_id}/cart-codes?include=gift-cards {"data": {"type": "cart-codes","attributes": {"code": "delete_guest_${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [included][0][id] cart_code_id
+ When I send a DELETE request: /guest-carts/${guestcart_id}/cart-codes/${cart_code_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_gift_card_code_to_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Create giftcode in Database: empty_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/cart-codes {"data": {"type": "cart-codes","attributes": {"code": "empty_${random}"}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] GROSS_MODE
+ And Response body parameter should be: [data][attributes][currency] EUR
+ And Response body parameter should be: [data][attributes][store] DE
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body parameter should not be EMPTY: [data][links][self]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/negative.robot
new file mode 100644
index 0000000..f0bbd5d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/negative.robot
@@ -0,0 +1,339 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart product configurable-product inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+# POST #
+Add_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "fake","quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 102
+ And Response should return error message: Product "fake" not found
+
+Add_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts//items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_item_to_cart_with_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=asdasfas
+ When I send a POST request: /carts/han/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "carts","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a POST request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"sku": "","quantity": "" }}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"0","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"-1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":"1","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+# PATCH #
+Update_item_in_cart_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+
+Update_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a PATCH request: /carts/${cart_uid}/items {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_item_in_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/fake/items/fake {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_in_cart_with_no_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ ... AND I send a POST request: /carts/${cart_uid}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts//items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_item_in_cart_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND I get access token for the customer: ${Yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity": 1}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Update_item_with_invalid_parameters
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid} {"data": {"type": "items","attributes": {"quantity":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+# DELETE #
+Delete_cart_item_with_non_existing_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_id
+ When I send a DELETE request: /carts/${cart_id}/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 103
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Delete_cart_item_with_empty_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /carts
+ ... AND Save value to a variable: [data][0][id] cart_uid
+ When I send a DELETE request: /carts/${cart_uid}/items
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_item_with_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts/fake/items/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_cart_item_with_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /carts//items/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/positive.robot
new file mode 100644
index 0000000..2e8c1ab
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_items/positive.robot
@@ -0,0 +1,356 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart product marketplace-product-options product-options non-splittable-products configurable-product promotions-discounts marketplace-promotions-discounts inventory-management marketplace-inventory-management
+
+*** Test Cases ***
+###POST#####
+
+Add_one_item_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Add_two_items_to_cart_with_included_items_concrete_products_and_abstract_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items?include=items,concrete-products,abstract-products {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 2}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 3
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][1][type] concrete-products
+ And Response body parameter should contain: [included][1][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][quantity] 2
+ And Response body parameter should contain: [included][2][attributes][groupKey] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][2][attributes][abstractSku] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][2][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][2][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][2][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Get_a_cart_with_included_items_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][items][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: items
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: items
+ And Response include element has self link: concrete-products
+ And Response body parameter should be: [included][1][type] items
+ And Response body parameter should contain: [included][1][id] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][quantity] 2
+ And Response body parameter should contain: [included][1][attributes][groupKey] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][1][attributes][abstractSku] ${product_availability.abstract_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][1][attributes][amount] None
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][1][attributes][calculations][sumPriceToPayAggregation]
+ And Response should contain the array of a certain size: [included][1][attributes][selectedProductOptions] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Add_five_items_to_cart_with_included_cart_rules_and_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items?include=cart-rules,promotional-items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 5}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should not be EMPTY: [data][relationships][cart-rules][data]
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: items
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}
+ ... AND Response status code should be: 204
+
+Add_product_with_options_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data":{"type":"items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product_with_concrete_product_alternative.sku}
+ ... AND Response status code should be: 204
+
+Add_item_with_storage_category_and_2_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 2}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] ${discount_concrete_product.product_1.total_sum_of_discounts}
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_2.name}
+ And Response body parameter should be: [data][attributes][discounts][0][amount] ${discount_concrete_product.product_1.with_discount_20_percentage_off_storage}
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should be: [data][attributes][discounts][1][displayName] ${discount_1.name}
+ And Response body parameter should be: [data][attributes][discounts][1][amount] ${discount_concrete_product.product_1.with_discount_10_percentage_off_minimum_order}
+ And Response body parameter should be: [data][attributes][discounts][1][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${concrete_product.product_without_relations}
+ ... AND Response status code should be: 204
+
+
+Add_a_configurable_product_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "config-product-to-cart-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a GET request: /carts/${cart_id}?include=items,concrete-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_1.name}
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+###### PATCH #######
+Change_item_qty_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be less than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+Change_item_amount_in_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type": "items","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be less than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${item_total_price}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}/items/${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ ... AND Response status code should be: 204
+
+
+Update_configurable_product_quantity_in_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "update-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 3
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /carts/${cart_id}/items/${item_uid}?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+####### DELETE #######
+Delete_item_form_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "delete-config-product-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ When I send a DELETE request: /carts/${cart_id}/items/${item_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}?include=items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/negative.robot
new file mode 100644
index 0000000..be12036
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core acl shared-carts
+
+*** Test Cases ***
+
+Get_cart_permission_group_with_unauthenicated_user
+ When I send a GET request: /cart-permission-groups/1
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_cart_permission_group_by_non_exist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/111111
+ Then Response status code should be: 404
+ And Response should return error code: 2501
+ And Response should return error message: Cart permission group not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/positive.robot
new file mode 100644
index 0000000..fb4d140
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/cart_permssion_groups/positive.robot
@@ -0,0 +1,79 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core acl shared-carts multiple-carts
+
+*** Test Cases ***
+Get_cart_permission_groups_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] company_user_id
+ ... AND I send a POST request: /carts/${cart_id}/shared-carts {"data": {"type": "shared-carts","attributes": {"idCompanyUser": "${company_user_id}","idCartPermissionGroup": "${cart_permission_group_id_2}"}}}
+ When I send a GET request: /carts/${cart_id}?include=shared-carts,cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][shared-carts]
+ And Each array element of array in response should contain property: [data][relationships][shared-carts][data] type
+ And Each array element of array in response should contain property: [data][relationships][shared-carts][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value in: [included] type cart-permission-groups shared-carts
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 2
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDefault]
+ And Response body parameter should be in: [included][0][attributes][isDefault] true false
+ And Response body parameter should be: [included][1][type] shared-carts
+ And Response body parameter should be: [included][1][attributes][idCompanyUser] ${company_user_id}
+ And Response body parameter should be: [included][1][attributes][idCartPermissionGroup] ${cart_permission_group_id_2}
+ And Response body parameter should not be EMPTY: [included][1][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property: [included][1][relationships][cart-permission-groups][data] type
+ And Each array element of array in response should contain property: [included][1][relationships][cart-permission-groups][data] id
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_all_cart_permission_groups
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type cart-permission-groups
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDefault] True False
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Get_cart_permission_groups_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /cart-permission-groups/${cart_permission_group_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter Should Be: [data][type] cart-permission-groups
+ And Response body parameter should Be: [data][id] ${cart_permission_group_id}
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][isDefault]
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/negative.robot
new file mode 100644
index 0000000..868de80
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/negative.robot
@@ -0,0 +1,408 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart customer-access spryker-core
+
+*** Test Cases ***
+#GET requests
+Get_cart_by_cart_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_cart_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/12345678
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_cart_by_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_customer_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=234567thgf
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_cart_by_customer_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_cart_with_non_existing_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/user-01/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+
+Get_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 802
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#POST requests
+Create_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+
+Create_cart_without_access_token
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_cart_with_invalid_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "D","name": "${test_cart_name}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 112
+ And Response should return error message: Store data is invalid.
+
+Create_cart_with_invalid_priceMod_and_currency
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "${store.de}","name": "${test_cart_name}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ And Response body parameter should be: [errors][2][code] 107
+ And Response body parameter should be: [errors][2][detail] Failed to create cart.
+
+Create_cart_with_empty_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": "","name": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail priceMode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail currency => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail store => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+
+Create_cart_without_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail priceMode => This field is missing.
+ And Array in response should contain property with value: [errors] detail currency => This field is missing.
+ And Array in response should contain property with value: [errors] detail store => This field is missing.
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+
+
+#PATCH requests
+Update_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=u2g3v4b6jk55b If-Match=ETag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Update_cart_without_access_token
+ [Setup] I set Headers: Authorization= If-Match=ETag
+ When I send a PATCH request: /carts/not-existing-cart {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+
+Update_cart_with_non_existing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Get ETag header value from cart
+ ... AND Response status code should be: 200
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/8567km {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Get ETag header value from cart
+ ... AND Response status code should be: 200
+ ... AND I set Headers: Authorization=${token} If-Match=${Etag}
+ When I send a PATCH request: /carts/ {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_from_another_customer_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match="3278654tv3"
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 412
+ And Response reason should be: Precondition Failed
+ And Response should return error message: If-Match header value is invalid.
+ And Response should return error code: 006
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_header_tag
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 428
+ And Response reason should be: Precondition Required
+ And Response should return error message: If-Match header is missing.
+ And Response should return error code: 005
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "car","attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"attributes": {"priceMode": "${mode.net}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: name => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_invalid_priceMod_currency_store
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "GROSS","currency": "EU","store": "DEK"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 117
+ And Response body parameter should be: [errors][0][detail] Currency is incorrect.
+ And Response body parameter should be: [errors][1][code] 119
+ And Response body parameter should be: [errors][1][detail] Price mode is incorrect.
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+
+#DELETE requests
+Delete_cart_with_invalid_access_token
+ [Setup] I set Headers: Authorization=iuhiu6gi7
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Delete_cart_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a DELETE request: /carts/not-existing-cart
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Delete_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/88ca6f79
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Delete_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_cart_from_another_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/positive.robot
new file mode 100644
index 0000000..e578845
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/carts/positive.robot
@@ -0,0 +1,438 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax promotions-discounts marketplace-promotions-discounts spryker-core customer-access multiple-carts
+
+*** Test Cases ***
+### GET requests
+Get_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_without_cart_id
+# Spryker is designed so that we can get all carts same as for /customers/{customerId}/carts request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] priceToPay
+ And Each array element of array in response should contain nested property: [data] [attributes] discounts
+ And Each array element of array in response should contain property: [data] links
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_by_cart_id_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_products.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_products.sku_2}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${concrete_products.sku_3}","quantity": 1}}}
+ When I send a GET request: /carts/${cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][items][data] 3
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Response body parameter should contain: [data][relationships][items][data][0][id] ${concrete_products.sku_1}
+ And Response body parameter should contain: [data][relationships][items][data][1][id] ${concrete_products.sku_2}
+ And Response body parameter should contain: [data][relationships][items][data][2][id] ${concrete_products.sku_3}
+ And Response should contain the array of a certain size: [included] 3
+ And Each array element of array in response should contain property with value: [included] type items
+ And Response body parameter should contain: [included][0][id] ${concrete_products.sku_1}
+ And Response body parameter should contain: [included][1][id] ${concrete_products.sku_2}
+ And Response body parameter should contain: [included][2][id] ${concrete_products.sku_3}
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_products.sku_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${concrete_products.sku_2}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][2][attributes][sku] ${concrete_products.sku_3}
+ And Response body parameter should be: [included][2][attributes][quantity] 1
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] salesUnit
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Get_cart_by_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data] ${cart_id}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] attributes priceMode
+ And Each array element of array in response should contain nested property: [data] attributes currency
+ And Each array element of array in response should contain nested property: [data] attributes store
+ And Each array element of array in response should contain nested property: [data] attributes name
+ And Each array element of array in response should contain nested property: [data] attributes isDefault
+ And Each array element of array in response should contain nested property: [data] attributes totals
+ And Each array element of array in response should contain nested property: [data] attributes discounts
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] priceToPay
+ And Each array element of array in response should contain nested property: [data] [attributes] discounts
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+###POST requests
+Create_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link for created entity: ${cart_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_cart_with_existing_name
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id_2
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id_2}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] None
+ And Response body parameter should be: [data][attributes][totals][discountTotal] None
+ And Response body parameter should be: [data][attributes][totals][taxTotal] None
+ And Response body parameter should be: [data][attributes][totals][subtotal] None
+ And Response body parameter should be: [data][attributes][totals][grandTotal] None
+ And Response body parameter should be: [data][attributes][totals][priceToPay] None
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link for created entity: ${cart_id_2}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /carts/${cart_id_2}
+ ... AND Response status code should be: 204
+
+###PATCH requests
+Update_cart_by_cart_id_with_all_attributes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "${mode.net}","currency": "${currency.chf.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.net}
+ And Response body parameter should be: [data][attributes][currency] ${currency.chf.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_empty_priceMod_currency_store
+# Spryker is designed so that we can send empty attributes: priceMod, currency, store and it will not be changed to the empty values.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_cart_with_name_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": "${test_cart_name}-${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][name] ${test_cart_name}-${random}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Get_cart_with_included_cart_rules
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Create empty customer cart: ${mode.gross} ${currency.eur.code} ${store.de} cart_rules
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": 4}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] 10% off minimum order
+ ### check discount amount ###
+ And Response body parameter should be: [data][attributes][discounts][0][amount] 3202
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 3202
+ ### check grand total with discount ###
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 28818
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Response body parameter should be: [included][0][attributes][amount] 3202
+ And Response body parameter should not be EMPTY: [included][0][attributes][amount]
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Get_cart_with_included_promotional_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Create empty customer cart: ${mode.gross} ${currency.eur.code} ${store.de} promotional
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}", "quantity": "8"}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}?include=promotional-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body should contain: discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] 10% off minimum order
+ And Response body parameter should be: [data][attributes][discounts][0][amount] 6404
+ And Each array element of array in response should contain property with value: [data][relationships][promotional-items][data] type promotional-items
+ And Each array element of array in response should contain property: [data][relationships][promotional-items][data] id
+ And Each array element of array in response should contain property with value: [included] type promotional-items
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should be in: [included][0][attributes][sku] 068 112
+ And Response body parameter should be in: [included][1][attributes][sku] 068 112
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+
+
+Update_cart_with_existing_name
+# Spryker is designed so that we can send existing name and it will be changed automatically to the unique value on the BE side.
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Save Header value to a variable: ETag header_tag
+ ... AND Response status code should be: 201
+ ... AND I set Headers: Authorization=${token} If-Match=${header_tag}
+ When I send a PATCH request: /carts/${cart_id} {"data": {"type": "carts","attributes": {"name": "My Cart"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should NOT be: [data][attributes][name] "My Cart"
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+###DELETE requests
+Delete_cart_by_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /carts/${cart_id}
+ Then Response status code should be: 404
+ And Array in response should contain property with value: [errors] detail Cart with given uuid not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/negative.robot
new file mode 100644
index 0000000..1e95510
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/negative.robot
@@ -0,0 +1,91 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart spryker-core
+
+*** Test Cases ***
+Get_guest_cart_without_anonymous_customer_unique_id
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_empty_anonymous_customer_unique_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Get_guest_cart_wth_non_existing_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a GET request: /guest-carts/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_wrong_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_with_empty_x_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+ And Response should return error code: 109
+
+Update_guest_cart_with_wrong_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/fake {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ And Response should return error code: 101
+
+Update_guest_cart_without_guest_cart_id
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/ {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+
+Update_guest_cart_with_invalid_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-car","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Update_guest_cart_without_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Update_guest_cart_update_price_mode_with_items_in_the_cart
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.net}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response body parameter should be: [errors][0][code] 111
+ And Response body parameter should be: [errors][0][detail] Can’t switch price mode when there are items in the cart.
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/positive.robot
new file mode 100644
index 0000000..e224401
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/guest_carts/positive.robot
@@ -0,0 +1,193 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart prices tax spryker-core customer-access marketplace-promotions-discounts promotions-discounts
+
+*** Test Cases ***
+Create_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product_with_concrete_product_alternative.sku}","quantity": 1}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain value: [data] guest-carts
+ And Each array element of array in response should contain nested property with datatype: [data] id str
+ And Each array element of array in response should contain nested property with value: [data] [attributes][priceMode] ${mode.gross}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][currency] ${currency.eur.code}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][store] ${store.de}
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals][expenseTotal] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][totals][discountTotal] int
+ And Each array element of array in response should be greater than: [data] [attributes][totals][taxTotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][subtotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][grandTotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_by_id
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+
+Retrieve_guest_cart_including_cart_items
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][relationships][guest-cart-items][data][0][type] guest-cart-items
+ And Response body parameter should contain: [data][relationships][guest-cart-items][data][0][id] ${concrete_product_with_concrete_product_alternative.sku}
+ And Each array element of array in response should contain nested property with value: [included] type guest-cart-items
+ And Each array element of array in response should contain nested property with datatype: [included] id str
+ And Response should contain the array of a certain size: [included] 1
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Each array element of array in response should contain value: [included] unitPrice
+ And Each array element of array in response should contain value: [included] sumPrice
+ And Each array element of array in response should contain value: [included] taxRate
+ And Each array element of array in response should contain value: [included] unitNetPrice
+ And Each array element of array in response should contain value: [included] sumNetPrice
+ And Each array element of array in response should contain value: [included] unitGrossPrice
+ And Each array element of array in response should contain value: [included] sumGrossPrice
+ And Each array element of array in response should contain value: [included] unitTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumTaxAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitSubtotalAggregation
+ And Each array element of array in response should contain value: [included] unitProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] sumProductOptionPriceAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountAggregation
+ And Each array element of array in response should contain value: [included] unitDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] sumDiscountAmountFullAggregation
+ And Each array element of array in response should contain value: [included] unitPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] sumPriceToPayAggregation
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+
+Retrieve_guest_cart_including_cart_rules
+ [Setup] Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 7
+ When I send a GET request: /guest-carts/${guest_cart_id}?include=cart-rules
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Each array element of array in response should contain property with value: [included] type cart-rules
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+
+Update_guest_cart_with_all_attributes
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Update_guest_cart_with_empty_priceMod_currency_store
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a PATCH request: /guest-carts/${guest_cart_id} {"data": {"type": "guest-carts","attributes": {"priceMode": "","currency": "","store": ""}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][subtotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][grandTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][priceToPay]
+ And Response body has correct self link internal
+
+Convert_guest_cart_to_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND Create a guest cart: ${random}-convert-guest-cart ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${guest_cart_id}?include=items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes][priceMode]
+ And Response body parameter should not be EMPTY: [data][attributes][currency]
+ And Response body parameter should not be EMPTY: [data][attributes][store]
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][taxTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/negative.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/negative.robot
new file mode 100644
index 0000000..c8eb13c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/negative.robot
@@ -0,0 +1,362 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart shared-carts customer-access spryker-core
+
+*** Test Cases ***
+Share_not_owned_shopping_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_non_existing_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: 422
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_with_empty_permission_group_value_and_company_user_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"","idCartPermissionGroup":""}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail idCartPermissionGroup => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail idCompanyUser => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+
+Share_shopping_cart_without_company_user_attribute_and_cart_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail idCompanyUser => This field is missing.
+ And Array in response should contain property with value: [errors] detail idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_the_other_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_seventh_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser": "${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 2703
+ And Response reason should be: Forbidden
+ And Response should return error message: Cart can be shared only with company users from same company.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_without_access_token
+ When I send a POST request: /carts/shoppingCartId/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Share_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a POST request: /carts/shoppingCartId/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Share_shopping_cart_with_empty_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts//shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 400
+ And Response should return error code: 104
+ And Response reason should be: Bad Request
+ And Response should return error message: Cart uuid is missing.
+
+Share_shopping_cart_with_incorrect_cart_permission_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":3}}}
+ Then Response status code should be: 422
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Share_shopping_cart_to_non_existing_company_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"nonExistingCompanyUserId","idCartPermissionGroup":2}}}
+ Then Response status code should be: 404
+ And Response should return error code: 1404
+ And Response reason should be: Not Found
+ And Response should return error message: Company user not found
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_access_token
+ When I send a PATCH request: /shared-carts/sharedCardId {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_permissions_of_shared_shopping_cart_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}1
+ When I send a PATCH request: /shared-carts/sharedCardId {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_permissions_of_shared_shopping_cart_without_shared_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /shared-carts {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_permissions_of_shared_shopping_cart_with_incorrect_permission_group
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":3}}}
+ Then Response status code should be: 422
+ And Response should return error code: 2501
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Cart permission group not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_extra_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"test123456","idCartPermissionGroup":1}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_with_empty_permission_group_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":""}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_without_permission_group_attribute
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ When I send a PATCH request: /shared-carts/${sharedCardId} {"data":{"type":"shared-carts","attributes":{}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: idCartPermissionGroup => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/${cartId}/items/${concrete_available_product.sku} {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_an_item_from_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}/items/${concrete_available_product.sku}
+ Then Response status code should be: 403
+ And Response should return error code: 115
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized cart action.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_shared_shopping_cart_by_user_without_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: 403
+ And Response should return error code: 2701
+ And Response reason should be: Forbidden
+ And Response should return error message: Action is forbidden.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_the_already_deleted_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND Save value to a variable: [data][id] sharedCardId
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I get access token for the customer: ${yves_shared_shopping_cart_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /shared-carts/${sharedCardId}
+ Then Response status code should be: 404
+ And Response should return error code: 2705
+ And Response reason should be: Not Found
+ And Response should return error message: Shared cart not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/positive.robot b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/positive.robot
new file mode 100644
index 0000000..43b3919
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/cart_endpoints/shared-carts/positive.robot
@@ -0,0 +1,205 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shared-carts product-relations customer-access spryker-core
+
+*** Test Cases ***
+Create_a_shared_shopping_cart_with_read_only_permissions_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ And I send a GET request: /carts/${cartId}?include=shared-carts
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][type] shared-carts
+ And Response body parameter should be: [data][relationships][shared-carts][data][0][id] ${sharedCartId}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] shared-carts
+ And Response body parameter should be: [included][0][id] ${sharedCartId}
+ And Response body parameter should be: [included][0][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [included][0][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ And I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ And Response status code should be: 200
+ And Response body parameter should be: [data][relationships][cart-permission-groups][data][0][type] cart-permission-groups
+ And Response body parameter should be: [data][relationships][cart-permission-groups][data][0][id] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][type] cart-permission-groups
+ And Response body parameter should be: [included][0][id] 1
+ And Response body parameter should be: [included][0][attributes][isDefault] True
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shared_shopping_cart_with_full_access_permissions
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ When I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] sharedCartId
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 2
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] FULL_ACCESS
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_permissions_of_shared_shopping_cart_by_Cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a PATCH request: /shared-carts/${sharedCartId} {"data":{"type":"shared-carts","attributes":{"idCartPermissionGroup":1}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shared-carts
+ And Response body parameter should be: [data][attributes][idCompanyUser] ${companyUserId}
+ And Response body parameter should be: [data][attributes][idCartPermissionGroup] 1
+ Then I get access token for the customer: ${companyUserEmail}
+ And I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cartId}?include=cart-permission-groups
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][cart-permission-groups]
+ And Each array element of array in response should contain property: [data][relationships][cart-permission-groups][data] type
+ And Each array element of array in response should contain property: [data][relationships][cart-permission-groups][data] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [included][0][attributes][name] READ_ONLY
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_item_to_the_shared_shopping_cart_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_an_item_quantity_at_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Save value to a variable: [included][0][id] itemId
+ ... AND Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] itemTotalPrice
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/${cartId}/items/${itemId}?include=items {"data":{"type":"items","attributes":{"quantity":2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cartId}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [included][0][id] ${itemId}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be greater than: [included][0][attributes][calculations][sumPriceToPayAggregation] ${itemTotalPrice}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_an_item_from_the_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts/${cartId}?include=items
+ ... AND Save value to a variable: [data][relationships][items][data][0][id] itemId
+ When I send a DELETE request: /carts/${cartId}/items/${itemId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cartId}
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_with_full_access_permissions_by_user_with_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete_available_product.sku}","quantity":2}}}
+ ... AND Response status code should be: 201
+ ... AND Get the first company user id and its' customer email
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Response status code should be: 201
+ ... AND I get access token for the customer: ${companyUserEmail}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_a_shared_shopping_cart_by_cart_owner
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a GET request: /company-users
+ ... AND Save value to a variable: [data][0][id] companyUserId
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] sharedCartId
+ When I send a DELETE request: /shared-carts/${sharedCartId}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/negative.robot b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/negative.robot
new file mode 100644
index 0000000..4793bdd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_by_invalid_id
+ When I send a GET request: /category-nodes/test
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
+
+Get_category_node_by_non_exist_id
+ When I send a GET request: /category-nodes/111111
+ Then Response status code should be: 404
+ And Response should return error code: 703
+ And Response should return error message: "Cant find category node with the given id."
+
+Get_absent_category_node
+ When I send a GET request: /category-nodes
+ Then Response status code should be: 400
+ And Response should return error code: 701
+ And Response should return error message: Category node id has not been specified or invalid.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/positive.robot b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/positive.robot
new file mode 100644
index 0000000..ac58492
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_nodes/positive.robot
@@ -0,0 +1,59 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_node_is_root_by_id
+ [Documentation] Step skip due to isse https://spryker.atlassian.net/browse/CC-25961
+ When I send a GET request: /category-nodes/${category_node_is_root_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_is_root_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ # And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][parents] 0
+ And Response should contain the array larger than a certain size: [data][attributes][children] 1
+ And Response body has correct self link internal
+
+Get_category_node_has_children_by_id
+ When I send a GET request: /category-nodes/${category_node_has_children_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_has_children_id}
+ And Response body parameter should be: [data][attributes][nodeId] ${category_node_has_children_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] nodeId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] name
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] order
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] children
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][children] parents
+ And Response body has correct self link internal
+
+
+Get_category_node_that_has_only_parents_by_id
+ When I send a GET request: /category-nodes/${category_node_has_only_parent_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] category-nodes
+ And Response body parameter should be: [data][id] ${category_node_has_only_parent_id}
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][nodeId] int
+ And Response Body parameter should have datatype: [data][attributes][order] int
+ And Response Body parameter should have datatype: [data][attributes][url] str
+ And Response should contain the array of a certain size: [data][attributes][children] 0
+ And Response should contain the array larger than a certain size: [data][attributes][parents] 0
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_trees/positive.robot b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_trees/positive.robot
new file mode 100644
index 0000000..63c852c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/category_endpoints/category_trees/positive.robot
@@ -0,0 +1,30 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue merchant-category category-management
+
+*** Test Cases ***
+Get_category_trees
+ When I send a GET request: /category-trees
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type category-trees
+ And Each array element of array in response should contain property with value: [data] id ${None}
+ And Response body parameter should be: [data][0][type] category-trees
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] nodeId
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] order
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] url
+ And Each array element of array in response should contain property: [data][0][attributes][categoryNodesStorage] children
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][2][name] ${category_nodes_storage_name}
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][2][url] ${category_nodes_storage_url}
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][2][children][0][nodeId]
+ And Response body parameter should not be EMPTY: [data][0][attributes][categoryNodesStorage][2][children][0][order]
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][2][children][0][name] ${subcategory_nodes_storage_name}
+ And Response body parameter should be: [data][0][attributes][categoryNodesStorage][2][children][0][url] ${subcategory_nodes_storage_url}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][2][children][0][children] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage] ${qty_of_categories_in_category_trees}
+ And Response should contain the array of a certain size: [data][0][attributes][categoryNodesStorage][2][children] ${qty_of_subcategories_in_category_trees}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/negative.robot b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/negative.robot
new file mode 100644
index 0000000..bc566d4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/negative.robot
@@ -0,0 +1,402 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product spryker-core
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id add include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+# POST requests
+Create_order_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=faketoken Content-Type=${default_header_content_type}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_order_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+ And Response should return error code: 1105
+
+Create_order_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_order_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+
+Create_order_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "fake_email","salutation": "Freulein","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+
+Create_order_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Create_order_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Create_order_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Create_order_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Billing address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+
+Create_order_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shipments": [{"requestedDeliveryDate": "2021-09-29", "idShipmentMethod": 1, "items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"], "shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false}}],"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+
+Create_order_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+
+Create_order_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_payment.method_name","paymentSelection": "fake_payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Checkout payment is not valid
+
+Create_order_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "","paymentMethodName": "","paymentSelection": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+
+Create_order_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+
+Create_order_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Shipment method not found.
+ And Response should return error code: 1102
+
+Create_order_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+
+Create_order_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": []}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1104
+ And Response should return error message: Cart is empty.
+
+Create_order_with_regular_shipment_&_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 0},"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4301
+ And Response should return error message: Single and multiple shipments attributes are not allowed in the same request.
+
+Create_order_with_split_shipments_&_invalid_delivery_date
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "None"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": "None"}]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shipments.0.requestedDeliveryDate => This value is not a valid date.
+ And Array in response should contain property with value: [errors] detail shipments.1.requestedDeliveryDate => This value is not a valid date.
+
+Create_order_with_split_shipments_&_invalid_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1102
+ And Response should return error message: Shipping address country not found for country code: fake_iso2Code
+
+Create_order_with_split_shipments_&_empty_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4302
+ And Response should return error message: Provided address is not valid. You can either provide address ID or address fields.
+
+Create_order_with_split_shipments_&_without_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"],"shippingAddress": {},"idShipmentMethod": 4,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: shipments.1.shippingAddress => This value should not be blank.
+
+Create_order_with_invalid_payment_method
+ [Documentation] bug https://spryker.atlassian.net/browse/CC-19269
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${random}","paymentMethodName": "${payment.method_name}","paymentSelection":"${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1108
+ And Response should return error message: "Payment method “%s” of payment provider “%s” is invalid."
+
+Create_order_with_two_payment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${random}"},{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "Invoice"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1107
+ And Response should return error message: Multiple payments are not allowed.
diff --git a/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/positive.robot b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/positive.robot
new file mode 100644
index 0000000..c478032
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout/positive.robot
@@ -0,0 +1,1011 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core cart checkout shipment marketplace-shipment order-management configurable-bundle promotions-discounts marketplace-promotions-discounts gift-cards configurable-product payments inventory-management marketplace-inventory-management default-run-feature
+
+*** Test Cases ***
+## Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id add include to the cart endpoint.
+## Example:
+##I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+## Save value to a variable: [included][0][id] test
+## I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#POST requests
+Create_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_include_orders
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_net_mode_&_chf_currency_&_express_shipment_method
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.net}","currency":"${currency.chf.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 12}}}
+ When I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 5},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+
+Create_order_with_split_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_1
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] concrete_product_2
+ ... AND Response body parameter should be: [data][type] carts
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_1}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete_product_2}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [included][0][attributes][shipments] 0
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 2
+
+Create_order_with_split_shipments_&_same_shipping_address
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_1
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] concrete_product_2
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name_1}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_1}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null},{"items": ["${concrete_product_2}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku_name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}
+ And Response body parameter should be: [included][0][attributes][items][1][quantity] 1
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+
+
+Create_order_with_same_items_in_different_shipments
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] concrete_product_1
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_second_user.salutation}","email": "${yves_second_user.email}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name_1}","paymentSelection": "${payment.selection_name}"}],"shipments": [{"items": ["${concrete_product_1}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 2,"requestedDeliveryDate": null},{"items": ["${concrete_product_1}"],"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": null}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response should contain certain number of values: [included][0][attributes] shipments 1
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain certain number of values: [included][0][attributes][expenses] idShipment 1
+
+Create_order_with_free_shipping_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 5}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": ${shipment.method_1.id}},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should be: [included][0][attributes][totals][expenseTotal] ${shipment.method_1.price_eur}
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 49000
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${discount_3.total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ And Response should contain the array of a certain size: [included][0][attributes][items] 5
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_1.name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.method_1.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultGrossPrice] ${shipment.method_1.price_eur}
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${shipment.method_1.price_eur}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_3.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_3.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+Create_order_with_2_product_discounts
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_1.sku}","quantity": 1}}}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${discount_concrete_product.product_2.sku}","quantity": 1}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}", "${discount_concrete_product.product_2.sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body has correct self link internal
+ And Save value to a variable: [included][0][attributes][totals][expenseTotal] expense_total_sum
+ And Save value to a variable: [included][0][attributes][totals][discountTotal] discount_total_sum
+ And Save value to a variable: [included][0][attributes][totals][subtotal] sub_total_sum
+ #discountTotal
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_1.total_sum_for_discounts_for_products_1_and_2} + ${discount_2.total_sum_for_discounts_for_products_1_2}
+ And Perform arithmetical calculation with two arguments: discount_total_sum ${discount_total_sum} + ${discount_3.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][discountTotal] ${discount_total_sum}
+ #grandTotal
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${sub_total_sum} - ${discount_total_sum}
+ And Perform arithmetical calculation with two arguments: grand_total_sum ${grand_total_sum} + ${expense_total_sum}
+ And Response body parameter with rounding should be: [included][0][attributes][totals][grandTotal] ${grand_total_sum}
+ #item 1 - "10% off minimum order" and "20% off cameras" discounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][calculatedDiscounts] 2
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_1.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_1.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_1.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_1.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][0][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ #item 2 - "10% off minimum order" and "20% off cameras" discounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][1][calculatedDiscounts] 2
+ And Response body parameter should be: [included][0][attributes][items][1][name] ${discount_concrete_product.product_2.name}
+ And Response body parameter should be: [included][0][attributes][items][1][sku] ${discount_concrete_product.product_2.sku}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_2.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_2.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_2.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_2.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][0][quantity] 1
+ #item 2 - "10% off minimum order" discount
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][unitAmount] ${discount_concrete_product.product_2.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_2.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][0][sumAmount] ${discount_concrete_product.product_2.discount_20_percentage_off_cameras_amount} ${discount_concrete_product.product_2.discount_10_percentage_off_above_100_amount}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][displayName] ${discount_1.name} ${discount_2.name}
+ And Response body parameter should be in: [included][0][attributes][items][1][calculatedDiscounts][1][description] ${discount_1.description} ${discount_2.description}
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][voucherCode] None
+ And Response body parameter should be: [included][0][attributes][items][1][calculatedDiscounts][1][quantity] 1
+ #calculatedDiscounts - "20% off storage" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_1.total_sum_for_discounts_for_products_1_and_2}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_1.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_1.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 2
+ #calculatedDiscounts - "10% off minimum order" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_2.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_2.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_2.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 2
+ #calculatedDiscounts - "Free standard delivery" discount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount: ${discount_3.total_sum_for_discounts_for_products_1_2}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName: ${discount_3.name}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description: ${discount_3.description}
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode: None
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity: 1
+
+Create_order_with_configurable_bundle_item
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 10,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_bundle_first_slot_item_sku}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_bundle_first_slot_item_name2}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_bundle_first_slot_item_sku2}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_checkout_with_gift_card
+ [Tags] skip-due-to-issue
+ [Documentation] bug https://spryker.atlassian.net/browse/CC-21301
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Create giftcode in Database: checkout_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=vouchers,gift-cards {"data": {"type": "cart-codes","attributes": {"code": "checkout_${random}"}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ AND Response body parameter should not be EMPTY: [data][attributes][orderReference]
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be: [included][0][attributes][payments][0][amount] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${gift_card.paymentProvider}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${gift_card.paymentMethod}
+ And Response body parameter should be greater than: [included][0][attributes][payments][1][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][1][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][1][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_checkout_with_gift_card_when_gift_amount_partially_used
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_alternative.product_sku1}","quantity": 1}}}
+ ... AND Create giftcode in Database: partially_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=vouchers,gift-cards {"data": {"type": "cart-codes","attributes": {"code": "partially_${random}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_alternative.product_sku1}"]}}}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_alternative.product_sku1}","quantity": 3}}}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=vouchers,gift-cards {"data": {"type": "cart-codes","attributes": {"code": "partially_${random}"}}}
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${concrete_product_with_alternative.product_sku1}"]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ AND Response body parameter should not be EMPTY: [data][attributes][orderReference]
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${concrete_product_with_alternative.product_sku1_name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${concrete_product_with_alternative.product_sku1}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][productOptions] 0
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumTaxAmount] 78
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumPriceToPayAggregation] 490
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be: [included][0][attributes][payments][0][amount] ${gift_card.amount}
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${gift_card.paymentProvider}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${gift_card.paymentMethod}
+
+ And Response body parameter should be greater than: [included][0][attributes][payments][1][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][1][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][1][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
+
+Create_order_with_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data":{"type":"items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Save value to a variable: [data][id] CartItemId
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ When I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${configurable_product.sku}"]}}}
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] checkout
+ And Response body parameter should be: [data][id] None
+ And Response body parameter should contain: [data][attributes][orderReference] ${store.de}--
+ And Response body parameter should be: [data][attributes][redirectUrl] None
+ And Response body parameter should be: [data][attributes][isExternalRedirect] None
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][relationships][orders][data][0][type] orders
+ And Response body parameter should contain: [data][relationships][orders][data][0][id] ${store.de}--
+ And Response body parameter should be: [included][0][type] orders
+ And Response body parameter should contain: [included][0][id] ${store.de}--
+ And Response body parameter should not be EMPTY: [included][0][attributes][createdAt]
+ And Response body parameter should be: [included][0][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [included][0][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [included][0][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [included][0][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [included][0][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ # #items
+ And Response body parameter should be: [included][0][attributes][items][0][name] ${configurable_product.name}
+ And Response body parameter should be: [included][0][attributes][items][0][sku] ${configurable_product.sku}
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [included][0][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [included][0][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [included][0][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [included][0][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][uuid]
+ And Response body parameter should be: [included][0][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [included][0][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [included][0][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [included][0][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [included][0][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][items][0][metadata][image]
+ And Response body parameter should be: [included][0][attributes][items][0][salesOrderItemConfiguration][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Each array element of array in response should contain property: [included][0][attributes][items] calculatedDiscounts
+ #expenses
+ And Response body parameter should be: [included][0][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [included][0][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [included][0][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [included][0][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idShipment]
+ And Response body parameter should not be EMPTY: [included][0][attributes][expenses][0][idSalesExpense]
+ #payments
+ And Response body parameter should be greater than: [included][0][attributes][payments][0][amount] 0
+ And Response body parameter should be: [included][0][attributes][payments][0][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [included][0][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [included][0][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [included][0][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [included][0][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [included][0][attributes][calculatedDiscounts] quantity
diff --git a/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/negative.robot b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/negative.robot
new file mode 100644
index 0000000..699325a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/negative.robot
@@ -0,0 +1,304 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment marketplace-shipment spryker-core
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#POST requests
+
+Provide_checkout_data_with_invalid_access_token
+ [Documentation] error message changed in https://spryker.atlassian.net/browse/CC-19340
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: One of Authorization or X-Anonymous-Customer-Unique-Id headers is required.
+ And Response should return error code: 1105
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "fake_type","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+Provide_checkout_data_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_without_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_email
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "fake_email","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: customer.email => Email is invalid.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "fake_cart_id","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+
+Provide_checkout_data_with_cart_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1103
+ And Response should return error message: Cart not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_empty_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "","salutation": "","firstName": "","lastName": ""},"idCart": "","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail customer.email => Email is invalid.
+
+Provide_checkout_data_without_customer_attributes_and_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {},"billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail idCart => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail customer.email => This field is missing.
+
+Provide_checkout_data_with_empty_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail billingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail billingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_with_empty_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","iso2Code": "","company": "","phone": "","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This value is too short. It should have 3 characters or more.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail shippingAddress.salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.city => This field is missing.
+ And Array in response should contain property with value: [errors] detail shippingAddress.iso2Code => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_with_empty_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "","paymentMethodName": ""}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This value should not be blank.
+ And Response should return error message: payments.0.paymentMethodName => This value should not be blank.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail payments.0.paymentMethodName => This field is missing.
+ And Array in response should contain property with value: [errors] detail payments.0.paymentProviderName => This field is missing.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+Provide_checkout_data_without_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: shipment.idShipmentMethod => This field is missing.
+ And Response should return error code: 901
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/positive.robot b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/positive.robot
new file mode 100644
index 0000000..2bd0744
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/checkout_endpoints/checkout_data/positive.robot
@@ -0,0 +1,202 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout payments shipment marketplace-shipment spryker-core
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#POST requests
+Provide_checkout_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_with_only_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data", "attributes": {"idCart": "${cart_id}","payments": []}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_billing_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipping_address_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "fake_salutation","firstName": "fake_first_name","lastName": "fake_last_name","address1": "fake_address1","address2": "fake_address2","address3": "fake_address3","zipCode": "fake_zipCode","city": "fake_city","iso2Code": "fake_iso2Code","company": "fake_company","phone": "fake_phone","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_payments
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "fake_provider_name","paymentMethodName": "fake_method_name"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_invalid_shipment_method_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 0},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedShipmentMethods] 0
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Provide_checkout_data_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${bundle_product.concrete.product_2_sku}","quantity": 1}}}
+ When I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] checkout-data
+ And Response body parameter should be: [data][id] None
+ And Response should contain the array of a certain size: [data][attributes][addresses] 0
+ And Response should contain the array of a certain size: [data][attributes][paymentProviders] 0
+ And Response should contain the array of a certain size: [data][attributes][shipmentMethods] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][id] 1
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][name] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be greater than: [data][attributes][selectedShipmentMethods][0][price] 0
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][taxRate] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][deliveryTime] None
+ And Response body parameter should be: [data][attributes][selectedShipmentMethods][0][currencyIsoCode] ${currency.eur.code}
+ And Response should contain the array of a certain size: [data][attributes][selectedPaymentMethods] 0
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/negative.robot
new file mode 100644
index 0000000..4ed72a6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/negative.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/3525626
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
+
+Request_company_without_access_token
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_company_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 404
+ And Response should return error code: 1801
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/positive.robot
new file mode 100644
index 0000000..e3bd0d6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/companies/positive.robot
@@ -0,0 +1,41 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_by_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /companies/mine
+ ... AND Save value to a variable: [data][0][id] company_id
+ When I send a GET request: /companies/${company_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] companies
+ And Response body parameter should be: [data][id] ${company_id}
+ And Response body parameter should be: [data][attributes][name] ${company_name}
+ And Response body parameter should be: [data][attributes][status] approved
+ And Response body parameter should be: [data][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][attributes] 3
+
+Request_company_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /companies/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] companies
+ And Response body parameter should be: [data][0][attributes][name] ${company_name}
+ And Response body parameter should be: [data][0][attributes][status] approved
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response should contain the array of a certain size: [data][0][attributes] 3
+ And Response body has correct self link
+
+
+
+
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/negative.robot
new file mode 100644
index 0000000..945aca2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/negative.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_unit_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/45768
+ Then Response status code should be: 404
+ And Response should return error code: 1901
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit not found.
+
+Request_business_unit_without_access_token
+ When I send a GET request: /company-business-units/456789
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_business_unit_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_business_unit_if_company_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 404
+ And Response should return error code: 1901
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/positive.robot
new file mode 100644
index 0000000..88b8fd4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_unit_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request: /company-business-units/${business_unit_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][attributes][name] ${business_unit_name}
+ And Response should contain the array of a certain size: [data][attributes] 7
+ And Response body parameter should be: [data][attributes][defaultBillingAddress] None
+ And Response body parameter should not be EMPTY: [data][attributes][email]
+ And Response body parameter should not be EMPTY: [data][attributes][phone]
+ And Response body parameter should contain: [data][attributes] externalUrl
+ And Response body parameter should contain: [data][attributes] bic
+ And Response body parameter should contain: [data][attributes] iban
+
+Request_business_unit_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] company-business-units
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][name] ${business_unit_name}
+ And Response should contain the array of a certain size: [data][0][attributes] 7
+
+Request_business_unit_by_id_with_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-business-units/mine
+ ... AND Save value to a variable: [data][0][id] business_unit_id
+ When I send a GET request: /company-business-units/${business_unit_id}?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-units
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should contain: [data][relationships] companies
+ And Response body parameter should contain: [data][relationships] company-business-unit-addresses
+
+Request_business_unit_by_mine_include_address_and_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-units/mine?include=company-business-unit-addresses,companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-business-units
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array of a certain size: [data][0][relationships] 2
+ Response body parameter should contain: [data][0][relationships] companies
+ Response body parameter should contain: [data][0][relationships] company-business-unit-addresses
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/negative.robot
new file mode 100644
index 0000000..12a7995
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/negative.robot
@@ -0,0 +1,39 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_unit_address_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/3456r7t8y8u
+ Then Response status code should be: 404
+ And Response should return error code: 2001
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit address not found.
+
+Request_business_unit_address_without_access_token
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_business_unit_address_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_business_unit_address_with_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/mine
+ Then Response status code should be: 404
+ And Response should return error code: 2001
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company business unit address not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/positive.robot
new file mode 100644
index 0000000..da11601
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_business_unit_addresses/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_business_units_address_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-business-unit-addresses/${busines_unit_address_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-business-unit-addresses
+ And Response body parameter should be: [data][id] ${busines_unit_address_id}
+ And Response should contain the array of a certain size: [data][attributes] 8
+ And Response body parameter should not be EMPTY: [data][attributes][address1]
+ And Response body parameter should not be EMPTY: [data][attributes][address2]
+ And Response body parameter should not be EMPTY: [data][attributes][zipCode]
+ And Response body parameter should not be EMPTY: [data][attributes][city]
+ And Response body parameter should not be EMPTY: [data][attributes][iso2Code]
+ And Response body parameter should not be EMPTY: [data][attributes][comment]
+ And Response body parameter should contain: [data][attributes] address3
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/negative.robot
new file mode 100644
index 0000000..94602ae
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/negative.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account
+
+*** Test Cases ***
+Request_company_role_by_wrong_ID
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/6334few7
+ Then Response status code should be: 404
+ And Response should return error code: 2101
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company role not found.
+
+Request_company_role_without_access_token
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response body parameter should be: [errors][0][detail] Missing access token.
+
+Request_company_role_with_wrong_access_token
+ [Setup] I set Headers: Authorization=sdrtfuygiuhoi
+ When I send a GET request: /company-roles/
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Invalid access token.
+
+Request_company_role_if_role_belong_to_other_users
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 404
+ And Response should return error code: 2101
+ And Response reason should be: Not Found
+ And Response body parameter should be: [errors][0][detail] Company role not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/positive.robot
new file mode 100644
index 0000000..ba4f689
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_roles/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+
+Test Tags glue spryker-core company-account
+
+
+*** Test Cases ***
+Request_company_role_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-roles
+ And Response body parameter should be in: [data][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+
+Request_company_role_by_mine
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 3
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Response body parameter should be in: [data][0][attributes][name] Buyer Admin
+ And Response body parameter should be in: [data][1][attributes][name] Admin Buyer
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be in: [data][1][attributes][isDefault] False True
+
+Request_company_role_by_mine_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /company-roles/mine?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-roles
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response body parameter should contain: [data][0][relationships][companies][data][0][type] companies
+
+Request_company_role_by_id_with_include_companies
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company_role_id
+ When I send a GET request: /company-roles/${company_role_id}?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][companies][data][0][type] companies
+ And Response body parameter should not be EMPTY: [data][relationships][companies][data][0][id]
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/negative.robot
new file mode 100644
index 0000000..5fff1ed
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/negative.robot
@@ -0,0 +1,68 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Request_access_token_by_invalid_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This is not a valid UUID.
+
+Request_access_token_by_empty_company_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: idCompanyUser => This value should not be blank.
+
+Request_access_token_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-access-tokens","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"","attributes":{"idCompanyUser":""}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Request_access_token_using_invalid_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=546789
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Request_access_token_with_missing_token
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"35235"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Request_access_token_if_user_belong_to_other_company
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 401
+ And Response should return error code: 003
+ And Response reason should be: Unauthorized
+ And Response body parameter should be: [errors][0][detail] Failed to authenticate user.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/positive.robot
new file mode 100644
index 0000000..a20c72b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_user_access_tokens/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Get_access_token_for_company_user_by_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][idCompanyUser] company_user
+ When I send a POST request: /company-user-access-tokens {"data":{"type":"company-user-access-tokens","attributes":{"idCompanyUser":"${company_user}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] company-user-access-tokens
+ And Response body parameter should be greater than: [data][attributes][expiresIn] 0
+ And Response body parameter should be less than: [data][attributes][expiresIn] 30000
+ And Response body parameter should not be EMPTY: [data][attributes][tokenType]
+ And Response body parameter should not be EMPTY: [data][attributes][accessToken]
+ And Response body parameter should not be EMPTY: [data][attributes][refreshToken]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/negative.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/negative.robot
new file mode 100644
index 0000000..b2accb5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/negative.robot
@@ -0,0 +1,48 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core company-account customer-account-management customer-access
+
+*** Test Cases ***
+Retrieve_list_of_company_users_without_access_token
+ When I send a GET request: /company-users
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+
+Retrieve_list_of_company_users_by_user_without_admin_role
+ When I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+
+Retrieve_company_user_by_incorrect_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/qwerty
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1404
+ And Response should return error message: Company user not found
+
+Retrieve_company_user_with_incorrect_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=qwerty
+ And I send a GET request: /company-users/qwerty
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Retrieve_user_who_doesn't_belong_to_company
+ When I get access token for the customer: ${yves_second_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 1403
+ And Response should return error message: Current company user is not set. You need to select the current company user with \/company-user-access-tokens in order to access the resource collection.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/positive.robot b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/positive.robot
new file mode 100644
index 0000000..4e52061
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/company_endpoints/company_users/positive.robot
@@ -0,0 +1,151 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core company-account customer-account-management customer-access
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Retrieve_list_of_company_users
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 12
+ And Response should contain the array of a certain size: [data][0] 4
+ And Each array element of array in response should contain value: [data] type
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Response should contain the array of a certain size: [data][0][attributes] 2
+ And Each array element of array in response should contain property with value in: [data] attributes.isActive True False
+ And Each array element of array in response should contain property with value in: [data] attributes.isDefault True False
+ And Response body has correct self link
+
+Retrieve_company_user_by_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/${company_user_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 4
+ And Response body parameter should contain: [data][type] company-users
+ And Response body parameter should contain: [data][id] ${company_user_id}
+ And Response should contain the array of a certain size: [data][attributes] 2
+ And Response body parameter should be in: [data][attributes][isActive] True False
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body has correct self link internal
+
+Retrieve_company_user_including_customers
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=customers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Response should contain the array of a certain size: [data][0][relationships][customers][data] 1
+ And Response should contain the array larger than a certain size: [included] 11
+ And Response include should contain certain entity type: customers
+ And Response include element has self link: customers
+
+Retrieve_company_user_including_company_business_units
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=company-business-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Each array element of array in response should contain property with value: [data][0][relationships][company-business-units][data] type company-business-units
+ And Response should contain the array of a certain size: [data][0][relationships][company-business-units][data] 1
+ And Response should contain the array larger than a certain size: [included] 6
+ And Response include should contain certain entity type: company-business-units
+ And Response include element has self link: company-business-units
+
+Retrieve_company_user_including_company_roles
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=company-roles
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Array element should contain nested array at least once: [data] [relationships]
+ And Response should contain the array of a certain size: [included] 6
+ And Response include should contain certain entity type: company-roles
+ And Response include element has self link: company-roles
+
+Retrieve_company_user_including_companies
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users?include=companies
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain value: [data] id
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+ And Each array element of array in response should contain nested property: [data] [attributes] isActive
+ And Each array element of array in response should contain nested property: [data] [attributes] isDefault
+ And Response should contain the array of a certain size: [data][0][relationships][companies][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: companies
+ And Response include element has self link: companies
+
+Retrieve_company_users_by_mine
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] company-users
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][attributes][isActive] True
+ And Response body parameter should be: [data][0][attributes][isDefault] False
+ And Response body has correct self link
+
+Retrieve_list_of_company_users_with_include_customers_and_filtered_by_company_role
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /company-roles/mine
+ ... AND Save value to a variable: [data][0][id] company-role-uuid
+ When I send a GET request: /company-users?include=customers&filter[company-roles.id]=${company-role-uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain property with value: [data] type company-users
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] relationships
+ And Response should contain the array of a certain size: [data][0][relationships] 1
+ And Response body parameter should contain: [data][0][relationships] customers
+
+Retrieve_list_of_company_users_if_user_has_4_companies
+ [Setup] Run Keywords I get access token for the customer: ${user_with_multiple_companies}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I add 'admin' role to company user and get company_user_uuid: ${user_with_multiple_companies} BoB-Hotel-Jim business-unit-jim-1
+ ... AND I get access token for the company user by uuid: ${company_user_uuid}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /company-users/mine
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 4
+ And Each array element of array in response should contain property with value: [data] type company-users
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
new file mode 100644
index 0000000..d69bf91
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Get_concrete_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${product_with_alternative.abstract_sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Get_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
new file mode 100644
index 0000000..1182e44
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_alternative_products/positive.robot
@@ -0,0 +1,55 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product discontinued-products alternative-products
+
+*** Test Cases ***
+Get_concrete_alternative_product_for_a_product_that_has_none
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body has correct self link
+ And Response reason should be: OK
+
+Get_concrete_alternative_product
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}/concrete-alternative-products
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response body should contain: id
+ And Response body parameter should not be EMPTY: [data][0][attributes][sku]
+ And Response body parameter should contain: [data][0][attributes] isDiscontinued
+ And Response body parameter should contain: [data][0][attributes] discontinuedNote
+ And Response body parameter should contain: [data][0][attributes] averageRating
+ And Response body parameter should contain: [data][0][attributes] reviewCount
+ And Response body parameter should not be EMPTY: [data][0][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should contain: [data][0][attributes] attributes
+ Response should contain the array of a certain size: [data][0][attributes][superAttributesDefinition] 3
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should contain: [data][0][attributes] attributeNames
+ And Response should contain the array of a certain size: [data][0][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][0][attributes][attributeNames] 6
+ And Response body has correct self link
+
+Get_concrete_alternative_product_with_include
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}/concrete-alternative-products?include=concrete-product-image-sets,concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should be: [data][0][type] concrete-products
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-availabilities
+ And Response include element has self link: concrete-product-prices
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
new file mode 100644
index 0000000..8e81458
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_abstract_SKU
+ When I send a GET request: /concrete-products/${abstract_available_product_with_stock.sku}/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_by_invalid_SKU
+ When I send a GET request: /concrete-products/124124/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 306
+ And Response should return error message: Availability is not found.
+
+Request_concrete_availability_with_missing_concrete_SKU
+ When I send a GET request: /concrete-products//concrete-product-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_concrete_availability_by_special_characters
+ When I send a GET request: /concrete-products/±!@#$%^&*()/concrete-product-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
new file mode 100644
index 0000000..42b42b1
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_availabilities/positive.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_availability_by_concrete_SKU_with_stock
+ When I send a GET request: /concrete-products/${concrete.available_product.with_stock.sku3}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete.available_product.with_stock.sku3}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 1
+ And Response body has correct self link
+
+Request_concrete_availability_by_concrete_SKU_with_stock_and_never_out_of_stock
+ When I send a GET request: /concrete-products/${concrete.available_product.with_stock_and_never_out_of_stock.sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete.available_product.with_stock_and_never_out_of_stock.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] True
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] True
+ And Response body parameter should be greater than: [data][0][attributes][quantity] 0
+ And Response body has correct self link
+
+
+Request_concrete_availability_by_concrete_SKU_without_stock
+ When I send a GET request: /concrete-products/${concrete.available_product.without_stock.sku}/concrete-product-availabilities
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${concrete.available_product.without_stock.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-availabilities
+ And Response body parameter should be: [data][0][attributes][availability] False
+ And Response body parameter should be: [data][0][attributes][isNeverOutOfStock] False
+ And Response body parameter should be: [data][0][attributes][quantity] ${stock_is_0}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
new file mode 100644
index 0000000..140d6c7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/negative.robot
@@ -0,0 +1,34 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_image_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.sku}/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
+
+Request_product_image_with_empty_SKU
+ When I send a GET request: /concrete-products//concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_image_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-image-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 304
+ And Response should return error message: Can`t find concrete product image sets.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
new file mode 100644
index 0000000..81c4b51
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_product_image_sets/positive.robot
@@ -0,0 +1,33 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_concrete_product_with_one_image_set
+ When I send a GET request: /concrete-products/${concrete_products.one_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_products.one_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets] 1
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 1
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
+
+Request_concrete_product_with_multiple_images
+ When I send a GET request: /concrete-products/${concrete_products.multiple_image_set.sku}/concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body has correct self link
+ And Response body parameter should be: [data][0][id] ${concrete_products.multiple_image_set.sku}
+ And Response body parameter should be: [data][0][type] concrete-product-image-sets
+ And Response body parameter should be: [data][0][attributes][imageSets][0][name] default
+ And Response body parameter should contain: [data][0][attributes] imageSets
+ And Response should contain the array of a certain size: [data][0][attributes][imageSets][0][images] 2
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlLarge]
+ And Response body parameter should not be EMPTY: [data][0][attributes][imageSets][0][images][0][externalUrlSmall]
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/negative.robot
new file mode 100644
index 0000000..5064008
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/negative.robot
@@ -0,0 +1,35 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_concrete_with_product_doesn't_exist
+ When I send a GET request: /concrete-products/354656u7i8
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Request_product_concrete_with_abstract_SKU
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_1_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+
+Request_product_concrete_with_empty_SKU
+ When I send a GET request: /concrete-products/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Request_product_concrete_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/positive.robot
new file mode 100644
index 0000000..9c6402b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products/positive.robot
@@ -0,0 +1,219 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product
+
+*** Test Cases ***
+Request_product_concrete_by_id
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${product_with_alternative.concrete_sku}
+ And Response body parameter should be: [data][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Response body parameter should be: [data][attributes][name] ${product_with_alternative.concrete_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+
+Request_product_concrete_with_included_image_sets
+ When I send a GET request: /concrete-products/${concrete_product.one_image_set.sku}?include=concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.one_image_set.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.one_image_set.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.one_image_set.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include element has self link: concrete-product-image-sets
+
+Request_product_concrete_with_included_abstract_product
+ When I send a GET request: /concrete-products/${product_with_alternative.concrete_sku}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${product_with_alternative.concrete_sku}
+ And Response body parameter should be: [data][attributes][sku] ${product_with_alternative.concrete_sku}
+ And Response body parameter should be: [data][attributes][name] ${product_with_alternative.concrete_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+
+Request_product_concrete_with_included_availabilities_and_product_prices
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /concrete-products/${concrete_product.original_prices.sku}?include=concrete-product-availabilities,concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.original_prices.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: concrete-product-availabilities
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-product-availabilities
+
+Request_product_concrete_with_included_sales_unit_and_product_measurement_units
+ When I send a GET request: /concrete-products/${concrete_product.product_with_sales_and_measurement_units.sku}?include=sales-units,product-measurement-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.product_with_sales_and_measurement_units.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.product_with_sales_and_measurement_units.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.product_with_sales_and_measurement_units.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 1
+ And Response should contain the array of a certain size: [data][attributes][attributes] 1
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include should contain certain entity type: sales-units
+ And Response include element has self link: product-measurement-units
+ And Response include element has self link: sales-units
+
+Request_product_concrete_with_included_product_labels_and_product_options
+ [Setup] Trigger product labels update
+ When I send a GET request: /concrete-products/${concrete_product.original_prices.sku}?include=product-labels,product-options
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.original_prices.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.original_prices.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-options
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-options
+
+Request_product_concrete_with_included_product_reviews
+ When I send a GET request: /concrete-products/${concrete_product.with_review.sku}?include=product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.with_review.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.with_review.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.with_review.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 6
+ And Response should contain the array of a certain size: [data][attributes][attributes] 6
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][attributes][averageRating]
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-reviews
+ And Response body has correct self link internal
+
+Request_product_concrete_with_included_product_offers
+ When I send a GET request: /concrete-products/${concrete_product.product_with_concrete_offers.sku}?include=product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${concrete_product.product_with_concrete_offers.sku}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_product.product_with_concrete_offers.sku}
+ And Response body parameter should be: [data][attributes][name] ${concrete_product.product_with_concrete_offers.name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 7
+ And Response should contain the array of a certain size: [data][attributes][attributes] 7
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response should contain the array of a certain size: [data][relationships][product-offers][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: product-offers
+ And Response include element has self link: product-offers
+
+Request_product_concrete_with_included_bundled_products
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}?include=bundled-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.bundle_product_product_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 2
+ And Response should contain the array of a certain size: [data][attributes][attributes] 2
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract.sku}
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] 3
+ And Response body parameter should be in: [data][relationships][bundled-products][data][0][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be in: [data][relationships][bundled-products][data][1][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be in: [data][relationships][bundled-products][data][2][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response should contain the array of a certain size: [included] 6
+ And Response include should contain certain entity type: bundled-products
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: bundled-products
+ And Response include element has self link: concrete-products
+
+Request_product_concrete_with_included_bundled_products_concrete_products_and_abstract_products
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_4_sku}?include=bundled-products,concrete-products,abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] concrete-products
+ And Response body parameter should be: [data][id] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_4_sku}
+ And Response body parameter should be: [data][attributes][name] ${bundle_product.bundle_product_product_name}
+ And Response should contain the array of a certain size: [data][attributes][attributeNames] 2
+ And Response should contain the array of a certain size: [data][attributes][attributes] 2
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should be: [data][attributes][productAbstractSku] ${bundle_product.abstract.sku}
+ And Response body parameter should not be EMPTY: [data][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][attributes][metaDescription]
+ And Response body parameter should be: [data][attributes][averageRating] None
+ And Response body parameter should be: [data][attributes][reviewCount] 0
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response should contain the array of a certain size: [data][relationships][abstract-products][data] 1
+ And Response body parameter should be: [data][relationships][abstract-products][data][0][id] ${bundle_product.abstract.sku}
+ And Response should contain the array of a certain size: [data][relationships][bundled-products][data] 3
+ And Response body parameter should be in: [data][relationships][bundled-products][data][0][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be in: [data][relationships][bundled-products][data][1][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response body parameter should be in: [data][relationships][bundled-products][data][2][id] ${bundle_product.concrete.product_3_sku} ${bundle_product.concrete.product_2_sku} ${bundle_product.concrete.product_1_sku}
+ And Response should contain the array of a certain size: [included] 16
+ And Response include should contain certain entity type: abstract-products
+ And Response include should contain certain entity type: bundled-products
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: abstract-products
+ And Response include element has self link: bundled-products
+ And Response include element has self link: concrete-products
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/negative.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/negative.robot
new file mode 100644
index 0000000..5e8c25a
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_product_prices_with_abstract_sku
+ When I send a GET request: /concrete-products/${bundle_product.abstract.product_2_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+Get_product_prices_with_empty_SKU
+
+ When I send a GET request: /concrete-products//concrete-product-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
+
+Get_product_prices_with_special_characters
+ When I send a GET request: /concrete-products/~!@#$%^&*()_+/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_product_prices_by_concrete_sku_product_doesn't_exist
+ When I send a GET request: /concrete-products/4567890/concrete-product-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 308
+ And Response should return error message: Can`t find concrete product prices.
+
+
+
+Request_URL_type_is_wrong
+ When I send a GET request: /concrete-product/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/positive.robot b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/positive.robot
new file mode 100644
index 0000000..7c7cfba
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/concrete_products_endpoints/concrete_products_prices/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue product prices
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+####GET####
+Get_concrete_product_with_only_default_price
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body has correct self link
+
+Get_concrete_product_with_default_and_original_prices
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices] 2
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body parameter should be: [data][0][attributes][prices][1][priceTypeName] ORIGINAL
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices][0][grossAmount]
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] netAmount ${None}
+ And Each array element of array in response should contain property with value: [data][0][attributes][prices] volumePrices ${arrow}
+ And Response body has correct self link
+
+Get_concrete_product_with_volume_product_prices
+ When I send a GET request: /concrete-products/${concrete_product.product_with_volume_prices.concrete_sku}/concrete-product-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_volume_prices.concrete_sku}
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] grossAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] netAmount
+ And Each array element of array in response should contain property: [data][0][attributes][prices][0][volumePrices] quantity
+ And Response body has correct self link
+
+Get_concrete_product_with_CHF_price_and_gross_mode
+ When I send a GET request: /concrete-products/${concrete_product.product_with_original_prices.concrete_sku}/concrete-product-prices?currency=${currency.chf.code}&priceMode=${mode.gross}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] concrete-product-prices
+ And Response body parameter should be: [data][0][id] ${concrete_product.product_with_original_prices.concrete_sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should contain: [data][0][attributes][prices] grossAmount
+ And Response body parameter should contain: [data][0][attributes][prices] netAmount
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should contain: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response body parameter should be: [data][0][attributes][prices][0][priceTypeName] DEFAULT
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot b/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
new file mode 100644
index 0000000..a92a2ed
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/negative.robot
@@ -0,0 +1,187 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+###### POST ######
+Add_configured_bundle_item_to_cart_non_existing_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "fake","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "fake" not found
+
+Add_configured_bundle_item_to_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Add_configured_bundle_item_to_missing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /carts//configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Add_configured_bundle_item_to_cart_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization="fake"
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_configured_bundle_item_to_cart_with_missing_token
+ When I send a POST request: /carts/fake/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_configured_bundle_item_to_cart_with_wrong_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "config","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_configured_bundle_item_to_cart_with_missing_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Add_configured_bundle_item_to_cart_with_invalid_properties
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": "","templateUuid": "","items": [{"sku": "","quantity": 2,"slotUuid": ""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Add_configured_bundle_item_to_cart_with_invalid_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles {"data": {"type": "configured-bundles","attributes": {"quantity": "abc"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 4003
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+####### PATCH #######
+Update_configured_bundle_item_in_cart_with_non_existing_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+
+Update_configured_bundle_item_in_cart_with_invalid_qty
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/${bundle_group_key}?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": "abc"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+
+Update_configured_bundle_item_in_cart_with_no_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/ {"data": {"type": "configured-bundles","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_item_in_cart_with_non_existing_cart_id
+
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts/fake/configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 1}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Update_configured_bundle_item_in_cart_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /carts//configured-bundles/fake {"data": {"type": "configured-bundles","attributes": {"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+####### DELETE #######
+Delete_configured_bundle_item_from_the_cart_with_wrong_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+
+Delete_configured_bundle_item_from_the_cart_with_empty_bundle_group_key
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_item_from_non_existing_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake/configured-bundles/fake
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Delete_configured_bundle_item_without_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts//configured-bundles/fake
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
diff --git a/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot b/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
new file mode 100644
index 0000000..6565c4c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configurable_bundle_endpoints/configurable_bundle/positive.robot
@@ -0,0 +1,86 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Add_configured_bundle_item_to_the_cart_with_included_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 10,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response should contain the array of a certain size: [data][relationships][items] 1
+ And Each array element of array in response should contain property with value: [data][relationships][items][data] type items
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][items][data] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle_first_slot_item_sku2}
+ And Response body parameter should be: [included][0][attributes][quantity] 10
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPriceToPayAggregation]
+
+Update_configured_bundle_quantity_in_the cart_to_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 10,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a PATCH request: /carts/${cart_id}/configured-bundles/${bundle_group_key}?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": 4}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [included][0][type] items
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle_first_slot_item_sku2}
+ And Response body parameter should be: [included][0][attributes][configuredBundle][quantity] 4
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 2
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+
+Delete_configured_bundle_item_from_the_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle_first_slot_item_sku2}","quantity": 10,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_group_key
+ ... AND Response status code should be: 201
+ When I send a DELETE request: /carts/${cart_id}/configured-bundles/${bundle_group_key}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /carts/${cart_id}
+ And Response body parameter should be: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot
new file mode 100644
index 0000000..eecd785
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Get_configurable_bundle_templates_by_invalid_configurable_bundle_template_id
+ When I send a GET request: /configurable-bundle-templates/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3901
+ And Response should return error message: Configurable bundle template not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot
new file mode 100644
index 0000000..486cc7b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/configured_bundles_templates/positive.robot
@@ -0,0 +1,109 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle
+
+*** Test Cases ***
+Get_configurable_bundle_templates
+ When I send a GET request: /configurable-bundle-templates
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_with_uuid
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response body has correct self link internal
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_slots
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-slots
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] relationships configurable-bundle-template-slots
+ And Each array element of array in response should contain property with value: [included] type configurable-bundle-template-slots
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_including_configurable_bundle_template_image_sets
+ When I send a GET request: /configurable-bundle-templates?include=configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Each array element of array in response should contain property with value: [data] type configurable-bundle-templates
+ And Each Array Element Of Array In Response Should Contain Property: [data] id
+ And Each Array Element Of Array In Response Should Contain Property: [data] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [data] links
+ And Each array element of array in response should contain nested property: [data] relationships configurable-bundle-template-image-sets
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Each array element of array in response should contain nested property: [included] attributes images
+ And Each array element of array in response should contain nested property: [included] [attributes][images] externalUrlLarge
+ And Each array element of array in response should contain nested property: [included] [attributes][images] externalUrlSmall
+ And Each array element of array in response should contain property with value: [included] type configurable-bundle-template-image-sets
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response body has correct self link
+
+Get_configurable_bundle_templates_by_configurable_bundle_template_1_uuid
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}?include=configurable-bundle-template-slots,configurable-bundle-template-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should be: [data][id] ${configurable_bundle_template_1_uuid}
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response should contain the array of a certain size: [data][relationships][configurable-bundle-template-slots][data] 4
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-slots][data] type configurable-bundle-template-slots
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response should contain the array of a certain size: [data][relationships][configurable-bundle-template-image-sets][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-image-sets][data] type configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain nested property: [included] attributes name
+ And Response include should contain certain entity type: configurable-bundle-template-slots
+ And Response include should contain certain entity type: configurable-bundle-template-image-sets
+ And Each array element of array in response should contain property: [included][4][attributes][images] externalUrlLarge
+ And Each array element of array in response should contain property: [included][4][attributes][images] externalUrlSmall
+
+Get_configurable_bundle_templates_including_concrete_products_concrete_product_prices_concrete_product_image_sets
+ When I send a GET request: /configurable-bundle-templates/${configurable_bundle_template_1_uuid}?include=configurable-bundle-template-slots,concrete-products,concrete-product-prices,concrete-product-image-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] configurable-bundle-templates
+ And Response body parameter should be: [data][id] ${configurable_bundle_template_1_uuid}
+ And Response body parameter should be: [data][attributes][name] ${configurable_bundle_template_name_1}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array larger than a certain size: [data][relationships][configurable-bundle-template-slots][data] 3
+ And Each array element of array in response should contain property with value: [data][relationships][configurable-bundle-template-slots][data] type configurable-bundle-template-slots
+ And Each array element of array in response should contain property: [data][relationships][configurable-bundle-template-slots][data] id
+ And Response include should contain certain entity type: configurable-bundle-template-slots
+ And Response include should contain certain entity type: concrete-product-image-sets
+ And Response include should contain certain entity type: concrete-product-prices
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-product-image-sets
+ And Response include element has self link: concrete-product-prices
+ And Response include element has self link: concrete-products
+ And Response include element has self link: configurable-bundle-template-slots
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot
new file mode 100644
index 0000000..69b18cb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/negative.robot
@@ -0,0 +1,217 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle spryker-core cart
+
+*** Test Cases ***
+### POST ###
+Add_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts/not_a_cart/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+
+Add_configured_bundle_with_empty_anonymous_id
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Add_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_with_empty_template_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4002
+ And Response should return error message: Configurable bundle template not found.
+
+Add_configured_bundle_with_nonexistant_template_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "not_uuid","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4002
+ And Response should return error message: Configurable bundle template not found.
+
+Add_configured_bundle_with_empty_slot_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": ""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Configured bundle cannot be added to cart.
+
+Add_configured_bundle_with_nonexistant_slot_uuid
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "not_uuid"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Configured bundle cannot be added to cart.
+
+Add_configured_bundle_with_zero_quantity
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 0,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: "Wrong quantity for product SKU ${configurable_bundle.slot_1.product_1}."
+
+Add_configured_bundle_with_empty_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "" not found
+
+Add_configured_bundle_with_invalid_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "not_a_sku","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "not_a_sku" not found
+
+Add_configured_bundle_with_abstract_product_sku
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${special_product_abstract_sku.with_multivariant}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product "${special_product_abstract_sku.with_multivariant}" not found
+
+Add_configured_bundle_with_product_not_in_stock
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts//guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_no_stock}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: Product ${configurable_bundle.slot_1.product_no_stock} is not available at the moment.
+
+### PATCH ###
+Update_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a PATCH request: /guest-carts/not_a_cart/guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_with_empty_anonymous_id
+ When I send a PATCH request: /guest-carts//guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Update_configured_bundle_quantity_to_zero
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 0}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4003
+ And Response should return error message: The quantity of the configured bundle should be more than zero.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Update_configured_bundle_with_empty_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/ {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Update_configured_bundle_with_invalid_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/not_a_bundle {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+### DELETE ###
+
+Delete_configured_bundle_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a DELETE request: /guest-carts/not_a_cart/guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_with_empty_anonymous_id
+ When I send a DELETE request: /guest-carts//guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_configured_bundle_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 4001
+ And Response should return error message: There was a problem adding or updating the configured bundle.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Delete_configured_bundle_with_empty_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/
+ Then Response status code should be: 400
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_configured_bundle_with_invalid_bundle_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND I send a POST request: /guest-carts//guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [data][id] guest_cart_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/not_a_bundle
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 4004
+ And Response should return error message: Configured bundle with provided group key not found in cart.
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot
new file mode 100644
index 0000000..22d1270
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/configured_bundles_endpoints/guest_configured_bundles/positive.robot
@@ -0,0 +1,305 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product configurable-bundle cart spryker-core promotions-discounts marketplace-promotions-discounts non-splittable-products
+
+*** Test Cases ***
+### POST ###
+Add_configured_bundle_with_1_slot_1_product_new_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_1_uuid}","items": [{"sku": "${configurable_bundle.slot_1.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_1_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 2
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_with_multiple_slots_and_products_to_existing_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id} {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_6.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_6_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 2
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_cart_rules
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=cart-rules {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: cart-rules
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][cart-rules][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][cart-rules][data] type cart-rules
+ And Each array element of array in response should contain property: [data][relationships][cart-rules][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] code
+ And Each array element of array in response should contain value: [included] discountType
+ And Each array element of array in response should contain value: [included] displayName
+ And Each array element of array in response should contain value: [included] isExclusive
+ And Each array element of array in response should contain value: [included] expirationDateTime
+ And Each array element of array in response should contain value: [included] discountPromotionAbstractSku
+ And Each array element of array in response should contain value: [included] discountPromotionQuantity
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_guest_cart_items
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][guest-cart-items][data] type guest-cart-items
+ And Each array element of array in response should contain property: [data][relationships][guest-cart-items][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPriceToPayAggregation]
+ And Each array element of array in response should contain value: [included] configuredBundle
+ And Response body parameter should be: [included][0][attributes][configuredBundle][quantity] 1
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][groupKey]
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][template]
+ And Response body parameter should be: [included][0][attributes][configuredBundle][template][uuid] ${configurable_bundle_template_2_uuid}
+ And Response body parameter should not be EMPTY: [included][0][attributes][configuredBundle][template][name]
+ And Each array element of array in response should contain value: [included] configuredBundleItem
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem][quantityPerSlot] 1
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem][slot][uuid] ${configurable_bundle_slot_5_uuid}
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 0
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_concrete_products
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=concrete-products,guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] guest_cart_id
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: concrete-products
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][0][id] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain property: [included] attributes
+ And Response body parameter should not be EMPTY: [included][0][attributes][sku]
+ And Response body parameter should not be EMPTY: [included][0][attributes][isDiscontinued]
+ And Response body parameter should be: [included][0][attributes][discontinuedNote] None
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][productAbstractSku]
+ And Response body parameter should not be EMPTY: [included][0][attributes][name]
+ And Response body parameter should not be EMPTY: [included][0][attributes][description]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributes]
+ And Response body parameter should not be EMPTY: [included][0][attributes][superAttributesDefinition]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaTitle]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [included][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [included][0][attributes][attributeNames]
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_include_bundle_items
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${bundle_product.concrete.product_4_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=bundle-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: bundle-items
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][relationships][bundle-items][data] 1
+ And Each array element of array in response should contain property with value: [data][relationships][bundle-items][data] type bundle-items
+ And Each array element of array in response should contain property: [data][relationships][bundle-items][data] id
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain value: [included] sku
+ And Each array element of array in response should contain value: [included] quantity
+ And Each array element of array in response should contain value: [included] groupKey
+ And Each array element of array in response should contain value: [included] abstractSku
+ And Each array element of array in response should contain value: [included] amount
+ And Each array element of array in response should contain value: [included] calculations
+ And Response body parameter should be: [included][0][attributes][configuredBundle] None
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem] None
+ And Each array element of array in response should contain value: [included] selectedProductOptions
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+Add_same_configured_bundle_again_to_check_quantity_not_merged
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [data][id] guest_cart_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_configured_bundle_to_cart_that_contains_same_product
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${configurable_bundle.slot_5.product_1} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_other_configured_bundle_product_with_same_template
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ And Save value to a variable: [data][id] guest_cart_id
+ And I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_2}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ Then Response status code should be: 201
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response include should contain certain entity type: guest-cart-items
+ And Response should contain the array of a certain size: [data][relationships][guest-cart-items][data] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Each array element of array in response should contain nested property with value: [included] [attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_bundle.slot_5.product_2}
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+
+### PATCH ###
+Update_configured_bundle_product_quantity
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a PATCH request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}?include=guest-cart-items {"data":{"type": "guest-configured-bundles","attributes":{"quantity": 2}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array larger than a certain size: [data][attributes][discounts] 0
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response should contain the array smaller than a certain size: [data][attributes][thresholds] 2
+ And Response body parameter should be: [data][links][self] ${current_url}/guest-carts/${guest_cart_id}
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_bundle.slot_5.product_1}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+### DELETE ###
+Delete_configured_bundle_from_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${abstract_available_product_with_stock.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-configured-bundles?include=guest-cart-items {"data": {"type": "guest-configured-bundles","attributes": {"quantity": 1,"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle.slot_5.product_1}","quantity": 1,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][attributes][configuredBundle][groupKey] bundle_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/guest-configured-bundles/${bundle_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/negative.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/negative.robot
new file mode 100644
index 0000000..ab753fb
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_page_list_by_fake_id
+ When I send a GET request: /cms-pages/:cms
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
+
+Get_cms_page_list_by_wrond_id
+ When I send a GET request: /cms-pages/${abstract_product_list.id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3801
+ And Response should return error message: Cms page not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/positive.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/positive.robot
new file mode 100644
index 0000000..b2723e4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/cms_pages/positive.robot
@@ -0,0 +1,82 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Resource ../../../../../../resources/steps/cms_steps.robot
+Test Tags glue cms content-item
+
+*** Test Cases ***
+Get_cms_pages_list
+ When I send a GET request: /cms-pages
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_pages.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value: [data] [attributes][isSearchable] True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body has correct self link
+
+Get_specific_cms_page
+ [Setup] Run Keywords I send a GET request: /cms-pages
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] cms_page_id
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_page_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_page_id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][url]
+ And Response body parameter should not be EMPTY: [data][attributes][isSearchable]
+ And Response body should contain: pageKey
+ And Response body should contain: validTo
+ And Response body has correct self link internal
+
+Get_cms_pages_with_Pagination
+ When I send a GET request: /cms-pages?page[limit]=10&page[offset]=0
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${cms_pages.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property with value: [data] type cms-pages
+ And Each array element of array in response should contain nested property with value: [data] [attributes][isSearchable] True
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain value: [data] pageKey
+ And Each array element of array in response should contain value: [data] name
+ And Each array element of array in response should contain value: [data] validTo
+ And Each array element of array in response should contain value: [data] url
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+
+Get_specific_cms_with_includes
+ [Setup] Add content product abstract list to cms page in DB ${cms_pages.cms_page_with_product_lists.id}
+ API_test_setup
+ When I send a GET request: /cms-pages/${cms_pages.cms_page_with_product_lists.id}?include=content-product-abstract-lists
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${cms_pages.cms_page_with_product_lists.id}
+ And Response body parameter should be: [data][type] cms-pages
+ And Response body parameter should be: [data][attributes][name] ${cms_pages.cms_page_with_product_lists.name}
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][content-product-abstract-lists][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: content-product-abstract-lists
+ And Response include element has self link: content-product-abstract-lists
+ [Teardown] Run Keyword Delete latest cms page version by uuid from DB ${cms_pages.cms_page_with_product_lists.id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/negative.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/negative.robot
new file mode 100644
index 0000000..6522be0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner_without_id
+ When I send a GET request: /content-banners
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_banner_with_wrong_content_id_type
+ When I send a GET request: /content-banners/${abstract_product_list.id}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 2203
+ And Response should return error message: Content type is invalid.
+
+Get_banner_with_invalid_content_id
+ When I send a GET request: /content-banners/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/positive.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/positive.robot
new file mode 100644
index 0000000..81065e3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_banners/positive.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue content-item
+
+*** Test Cases ***
+Get_banner
+ When I send a GET request: /content-banners/${banner_1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${banner_1.id}
+ And Response body parameter should be: [data][type] content-banners
+ And Response body parameter should be: [data][attributes][title] ${banner_1.title}
+ And Response body parameter should not be EMPTY: [data][attributes][subtitle]
+ And Response body parameter should contain: [data][attributes][imageUrl] jpg
+ And Response body parameter should not be EMPTY: [data][attributes][clickUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][altText]
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/negative.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/negative.robot
new file mode 100644
index 0000000..5cd7706
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Get_abstract_product_list_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_products_by_fake_id
+ When I send a GET request: /content-product-abstract-lists/fake/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
+Get_abstract_product_list_with_no_id
+ When I send a GET request: /content-product-abstract-lists
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_missing_id
+ When I send a GET request: /content-product-abstract-lists//abstract-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 2202
+ And Response should return error message: Content key is missing.
+
+Get_abstract_product_list_products_with_no_id
+ When I send a GET request: /content-product-abstract-lists/abstract-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 2201
+ And Response should return error message: Content item not found.
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/positive.robot b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/positive.robot
new file mode 100644
index 0000000..7319a46
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/content_endpoints/content_product_abstract_lists/positive.robot
@@ -0,0 +1,40 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product content-item
+
+*** Test Cases ***
+Abstract_product_list
+ When I send a GET request: /content-product-abstract-lists/${abstract_product_list.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product_list.id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+
+Abstract_product_list_abstract_products
+ When I send a GET request: /content-product-abstract-lists/${abstract_product_list.id}/abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_product_list.size}
+ And Each array element of array in response should contain property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][attributes][sku] ${abstract_product_list.product1_sku}
+ And Response body parameter should be: [data][0][attributes][name] ${abstract_product_list.product1_name}
+ And Response body parameter should be: [data][1][attributes][sku] ${abstract_product_list.product2_sku}
+ And Response body parameter should be: [data][1][attributes][name] ${abstract_product_list.product2_name}
+
+Abstract_product_list_with_include
+ When I send a GET request: /content-product-abstract-lists/${abstract_product_list.id}?include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${abstract_product_list.id}
+ And Response body parameter should be: [data][type] content-product-abstract-lists
+ And Response body has correct self link internal
+ And Response should contain the array of a certain size: [data][relationships][abstract-products][data] ${abstract_product_list.size}
+ And Response should contain the array of a certain size: [included] ${abstract_product_list.size}
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/negative.robot
new file mode 100644
index 0000000..eb290f4
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/negative.robot
@@ -0,0 +1,310 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+#POST#
+Create_customer_address_with_missing_required_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"address3": "${default.address3}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail address1 => This field is missing.
+ And Array in response should contain property with value: [errors] detail address2 => This field is missing.
+ And Array in response should contain property with value: [errors] detail zipCode => This field is missing.
+ And Array in response should contain property with value: [errors] detail city => This field is missing.
+ And Array in response should contain property with value: [errors] detail iso2Code => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultShipping => This field is missing.
+ And Array in response should contain property with value: [errors] detail isDefaultBilling => This field is missing.
+
+Create_customer_address_with_empty_fields
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "","firstName": "","lastName": "","address1": "","address2": "","address3": "","zipCode": "","city": "","country": "","iso2Code": "","company":"","phone": "","isDefaultShipping": "","isDefaultBilling": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+
+Create_customer_address_with_invalid_salutation_bug
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "Fake","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation => The value you selected is not a valid choice.
+
+Create_customer_address_with_customer_reference_not_matching_token
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_non_existing_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/DE--10000/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_customer_reference
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers//addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+
+Create_customer_address_with_empty_type
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+#GET#
+Get_non-existent_customer_address
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a GET request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Get_other_customer_address_list
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_address_list_for_non-existent_customer
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/fake/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+
+Get_address_list_with_no_token
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Get_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_other_customer_address_by_id_and_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+#PATCH#
+Patch_customer_address_without_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Patch_customer_address_with_fake_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a PATCH request: /customers/${yves_user.reference}/addresses/fake {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Patch_another_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_another_customer_address_by_id_using_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a PATCH request: /customers/${yves_second_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_no_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers//addresses/${address_uid} {"data": {"salutation": "${yves_second_user.salutation}","type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_wrong_reference
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/DE--1/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Patch_customer_address_with_empty_required_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"salutation": "${yves_second_user.salutation}","type": "addresses","attributes": {"salutation": null,"firstName": null,"lastName": null, "address1": null,"address2": null,"zipCode": null,"city": null,"iso2Code": null}}}
+ Then Response status code should be: ${422}
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address1 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail address2 => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail zipCode => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail city => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail iso2Code => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+Patch_customer_address_with_invalid_salutation_bug_CC-15866
+ [Documentation] Bug CC-15866
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"salutation": "Fake"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: salutation => The value you selected is not a valid choice.
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+
+#DELETE#
+Delete_customer_address_with_wrong_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+
+Delete_customer_address_with_no_id
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ And I send a DELETE request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_other_customer_address_by_id
+ [Setup] Run keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /customers/${yves_second_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ When I get access token for the customer: ${yves_user.email}
+ And I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Address was not found.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${yves_second_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/positive.robot
new file mode 100644
index 0000000..8466160
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/addresses/positive.robot
@@ -0,0 +1,245 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core
+
+*** Test Cases ***
+#POST#
+Create_customer_address_with_all_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+Create_customer_address_only_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] address_uid_1
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][address3] None
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] None
+ And Response body parameter should be: [data][attributes][phone] None
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ And Response body has correct self link for created entity: ${address_uid_1}
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid_1}
+ ... AND Response status code should be: 204
+
+
+
+Create_customer_address_as_shipping_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": true,"isDefaultBilling": false}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+Create_customer_address_as_billing_default
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] first_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": true}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] shipping_address_uid
+ And Response body parameter should be: [data][attributes][isDefaultShipping] False
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a GET request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] False
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${shipping_address_uid}
+ ... AND Response status code should be: 204
+
+#GET
+Get_empty_list_of_customer_addresses
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ And I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ Response should contain the array of a certain size: [data] 0
+
+Get_list_of_customer_addresses_with_1_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] address_uid
+ And Response body parameter should be: [data][0][type] addresses
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][address1] ${default.address1}
+ And Response body parameter should be: [data][0][attributes][address2] ${default.address2}
+ And Response body parameter should be: [data][0][attributes][address3] ${default.address3}
+ And Response body parameter should be: [data][0][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][0][attributes][city] ${default.city}
+ And Response body parameter should be: [data][0][attributes][country] ${default.country}
+ And Response body parameter should be: [data][0][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][0][attributes][company] ${default.company}
+ And Response body parameter should be: [data][0][attributes][phone] ${default.phone}
+ And Response body parameter should be: [data][0][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][0][attributes][isDefaultBilling] True
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
+
+Get_list_of_customer_addresses_with_2_addresses
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": true,"isDefaultBilling": true}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 2
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Save value to a variable: [data][0][id] first_address_uid
+ And Response body parameter should not be EMPTY: [data][1][id]
+ And Save value to a variable: [data][1][id] second_address_uid
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${first_address_uid}
+ ... AND Response status code should be: 204
+ ... AND I send a DELETE request: /customers/${yves_user.reference}/addresses/${second_address_uid}
+ ... AND Response status code should be: 204
+
+#DELETE
+Delete_customer_address
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /customers/${yves_user.reference}/addresses
+ ... AND Response status code should be: 200
+ ... AND Response should contain the array of a certain size: [data] 1
+ ... AND Save value to a variable: [data][0][id] address_uid
+ When I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /customers/${yves_user.reference}/addresses
+ Then Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+
+
+#PATCH
+Update_customer_address_several_fields
+ [Setup] Run keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Cleanup existing customer addresses: ${yves_user.reference}
+ ... AND I send a POST request: /customers/${yves_user.reference}/addresses {"data": {"type": "addresses","attributes": {"customer_reference": "${yves_user.reference}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","country": "${default.country}","iso2Code": "${default.iso2Code}","company":"${default.company}","phone": "${default.phone}","isDefaultShipping": ${default.shipping_status},"isDefaultBilling": ${default.billing_status}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] address_uid
+ ... AND Response body parameter should be: [data][attributes][isDefaultBilling] True
+ When I send a PATCH request: /customers/${yves_user.reference}/addresses/${address_uid} {"data": {"type": "addresses","attributes": {"address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","phone": "${changed.phone}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${address_uid}
+ And Response body parameter should be: [data][type] addresses
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][address1] ${changed.address1}
+ And Response body parameter should be: [data][attributes][address2] ${changed.address2}
+ And Response body parameter should be: [data][attributes][address3] ${changed.address3}
+ And Response body parameter should be: [data][attributes][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][city] ${default.city}
+ And Response body parameter should be: [data][attributes][country] ${default.country}
+ And Response body parameter should be: [data][attributes][iso2Code] ${default.iso2Code}
+ And Response body parameter should be: [data][attributes][company] ${default.company}
+ And Response body parameter should be: [data][attributes][phone] ${changed.phone}
+ And Response body parameter should be: [data][attributes][isDefaultShipping] True
+ And Response body parameter should be: [data][attributes][isDefaultBilling] True
+ [Teardown] Run Keywords I send a DELETE request: /customers/${yves_user.reference}/addresses/${address_uid}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/negative.robot
new file mode 100644
index 0000000..1b5e429
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/negative.robot
@@ -0,0 +1,11 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Access_restricted_resource_as_not_authorized_customer
+ I send a GET request: /wishlists
+ Response status code should be: 403
+ And Response reason should be: Forbidden
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/positive.robot
new file mode 100644
index 0000000..06a2fbd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_access/positive.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue customer-access customer-account-management spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Resources_list_which_customer_can_access
+ I send a GET request: /customer-access
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should contain: [data][0][type] customer-access
+ And Response should contain the array of a certain size: [data][0][attributes] [resourceTypes] 2
+ And Response body parameter should be: [data][0][attributes][resourceTypes][0] wishlists
+ And Response body parameter should be: [data][0][attributes][resourceTypes][1] wishlist-items
+ And Response body has correct self link
+
+Access_restricted_resource_as_authorized_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ I send a GET request: /wishlists
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should contain: [data][0][type] wishlists
+ And Response body parameter should be: [data][0][id] ${wishlist_id}
+ And Response body parameter should be: [data][0][attributes][numberOfItems] 1
+ And Response body parameter should be: [data][0][attributes][name] ${random}
+ And Response body has correct self link
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/negative.robot
new file mode 100644
index 0000000..c471c24
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/negative.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation_with_wrong_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"39085d16b04b34265910c7ea2a35367ggh"}}}
+ Response status code should be: 422
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ And Response should return error code: 423
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":""}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_without_confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{}}}
+ Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: registrationKey => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_empty_type
+ And I send a POST request: /customer-confirmation {"data":{"type":"","attributes":{"registrationKey":"607a17d1c673f461ca40002ea79fddc0"}}}
+ Response status code should be: 400
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Customer_confirmation_with_already_used_confirmation_key
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 423
+ And Response should return error message: This email confirmation code is invalid or has been already used.
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/positive.robot
new file mode 100644
index 0000000..9daba18
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_confirmation/positive.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Customer_confirmation
+ [Setup] Run Keywords I send a POST request: /customers {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com","password":"${yves_third_user.password_new}","confirmPassword":"${yves_third_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ When I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${yves_third_user.first_name}.${yves_third_user.last_name}${random}@spryker.com ${yves_third_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/negative.robot
new file mode 100644
index 0000000..6c383d3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/negative.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_wrong_email_format
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"123"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_empty_email
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Forgot_password_incorrect_type
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/positive.robot
new file mode 100644
index 0000000..b222fb8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_forgotten_password/positive.robot
@@ -0,0 +1,10 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Forgot_password_with_all_required_fields_and_valid_data
+ I send a POST request: /customer-forgotten-password {"data":{"type":"customer-forgotten-password","attributes":{"email":"${yves_user.email}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/negative.robot
new file mode 100644
index 0000000..f1ceb01
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/negative.robot
@@ -0,0 +1,125 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_not_equal_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field newPassword should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_data_type
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_current_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"","newPassword":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: newPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_empty_new_password_confirmation
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_non_autorizated_user
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_not_valid_user_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new_additional}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 408
+ And Response should return error message: Invalid password
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_short_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"test","confirmPassword":"test"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_too_long_password
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail newPassword => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_customer_reference
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/ {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password_new}","newPassword":"1234567890123","confirmPassword":"1234567890123"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_missing_mandatory_fields
+ Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/test123 {"data":{"type":"customer-password","attributes":{"newPassword":"${yves_user.password}"}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_customer_password_with_invalid_access_token
+ Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ AND I send a PATCH request: /customer-password/${yves_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_user.password}","newPassword":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/positive.robot
new file mode 100644
index 0000000..212c8b5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_password/positive.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Update_customer_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][attributes][accessToken] token
+ When I set Headers: Authorization=Bearer ${token}
+ AND I send a PATCH request: /customer-password/${yves_eighth_user.reference} {"data":{"type":"customer-password","attributes":{"password":"${yves_eighth_user.password}","newPassword":"${yves_eighth_user.password_new}","confirmPassword":"${yves_eighth_user.password_new}"}}}
+ Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new_additional}"}}}
+ Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 003
+ And Response should return error message: Failed to authenticate user.
+ And I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${yves_eighth_user.email}","password":"${yves_eighth_user.password_new}"}}}
+ And Response status code should be: 201
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/negative.robot
new file mode 100644
index 0000000..0a356d3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/negative.robot
@@ -0,0 +1,84 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_without_customer_id
+ I send a PATCH request: /customer-restore-password/ {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_type
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"fake","attributes":{"restorePasswordKey":"5ec608df9c0dd57c3dd08b540d4a68da","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_without_restorePasswordKey
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"","password":"${yves_user.password}","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: restorePasswordKey => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"","confirmPassword":"${yves_user.password}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_empty_new_confirmation_password_value
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"${yves_user.password}","confirmPassword":""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_short_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"test","confirmPassword":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_too_long_new_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"a46b40a8e1befff4cf0df9c7c2ace5f2","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail password => This value is too long. It should have 128 characters or less.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_not_equal_new_password_and_confirm_password
+ I send a PATCH request: /customer-restore-password/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password_new_additional}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 406
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Restore_password_with_incorrect_url
+ I send a PATCH request: /customer-restorepassword/${yves_user.reference} {"data":{"type":"customer-restore-password","attributes":{"restorePasswordKey":"aa2fbd68447da919fcb7da1a8d2d3c7a","password":"${yves_user.password}","confirmPassword":"${yves_user.password_new}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/positive.robot
new file mode 100644
index 0000000..a14614e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customer_restore_password/positive.robot
@@ -0,0 +1,23 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Restore_password_with_all_required_fields_and_valid_data
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_ninth_user.first_name}","lastName":"${yves_ninth_user.last_name}","gender":"${gender.female}","salutation":"${yves_ninth_user.salutation}","email":"${email.name}${random}${email.domain}","password":"${yves_ninth_user.password}","confirmPassword":"${yves_ninth_user.password}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] user_reference_id
+ ... AND Save value to a variable: [data][attributes][email] user_email
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_reference_id}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I send a POST request: /customer-forgotten-password {"data": {"type": "customer-forgotten-password","attributes": {"email":"${user_email}"}}}
+ ... AND Save the result of a SELECT DB query to a variable: select restore_password_key from spy_customer where customer_reference = '${user_reference_id}' restore_key
+ When I send a PATCH request: /customer-restore-password/${user_reference_id} {"data":{"type":"customer-restore-password","id":"${user_reference_id}","attributes":{"restorePasswordKey":"${restore_key}","password":"${yves_ninth_user.password_new}","confirmPassword":"${yves_ninth_user.password_new}"}}}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I get access token for the customer: ${user_email} ${yves_ninth_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /customers/${user_reference_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/negative.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/negative.robot
new file mode 100644
index 0000000..d0bbead
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/negative.robot
@@ -0,0 +1,244 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Create_a_customer_with_already_existing_email
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 400
+ And Response should return error message: If this email address is already in use, you will receive a password reset link. Otherwise you must first validate your e-mail address to finish registration. Please check your e-mail.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_short_password
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"Test12!","confirmPassword":"Test12!","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_too_long_password
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","confirmPassword":"Change!23456pqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuioppqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwertyuiopqwert","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: password => This value is too long. It should have 128 characters or less.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_equal_passwords
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"1234567890123","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 406
+ And Response should return error message: Value in field password should be identical to value in the confirmPassword field.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_not_accepted_terms_and_coditions
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":false}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_type
+ I send a POST request: /customers/ {"data":{"type":"","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":false}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_empty_values_for_required_fields
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail acceptedTerms => This value should be true.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_absent_type
+ I send a POST request: /customers/ {"data":{"attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_wrong_email_format
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"test.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: email => This value is not a valid email address.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_missing_required_fields
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail email => This field is missing.
+ And Array in response should contain property with value: [errors] detail salutation => This field is missing.
+ And Array in response should contain property with value: [errors] detail firstName => This field is missing.
+ And Array in response should contain property with value: [errors] detail lastName => This field is missing.
+ And Array in response should contain property with value: [errors] detail password => This field is missing.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This field is missing.
+ And Array in response should contain property with value: [errors] detail acceptedTerms => This field is missing.
+ And Array in response should contain property with value: [errors] detail gender => This field is missing.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_customer_with_wrong_gender
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+
+Get_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/DE35
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_cusomer_without_access_token
+ I send a GET request: /customers/DE35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_a_customer_with_access_token_from_another_user
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_second_user.reference}
+ Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 402
+ And Response should return error message: Customer not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_wrong_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/DE--30 {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"","lastName":"","gender":"","salutation":"","email":"","password":"","confirmPassword":"","acceptedTerms":false}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail firstName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail lastName => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail email => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail password => This value is too short. It should have 12 characters or more.
+ And Array in response should contain property with value: [errors] detail confirmPassword => This value is too short. It should have 12 characters or more.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_absent_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_with_invalid_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"test","salutation":"test","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail gender => The value you selected is not a valid choice.
+ And Array in response should contain property with value: [errors] detail salutation => The value you selected is not a valid choice.
+
+Update_a_customer_without_access_token
+ I send a PATCH request: /customers/DE--35 {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${yves_third_user.first_name}@spryker.com","password":"${yves_user.password}","confirmPassword":"${yves_user.password}","acceptedTerms":true}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_cusomer_without_access_token
+ I send a DELETE request: /customers/DE--35
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_without_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+Delete_a_customer_with_access_token_from_another
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/DE--30
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Delete_a_customer_with_invalid_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/fake-id
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 411
+ And Response should return error message: Unauthorized request.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
diff --git a/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/positive.robot b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/positive.robot
new file mode 100644
index 0000000..1a2aa0c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/customer_endpoints/customers/positive.robot
@@ -0,0 +1,116 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue customer-access customer-account-management spryker-core mailing-notifications
+
+*** Test Cases ***
+Create_customer
+ I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 201
+ And Save value to a variable: [data][id] user_id
+ And Save value to a variable: [data][attributes][email] userEmail
+ And Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${user_id}' confirmation_key
+ And I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ And I get access token for the customer: ${userEmail} ${yves_user.password_new}
+ And I set Headers: Authorization=${token}
+ And I send a GET request: /customers/${user_id}
+ And Response reason should be: OK
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${user_id}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_third_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_third_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${userEmail}
+ And Response body parameter should be: [data][attributes][gender] ${gender.male}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_third_user.salutation}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ [Teardown] Run Keywords I send a DELETE request: /customers/${user_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+New_customer_can_login_after_confirmation
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${email.name}${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] userId
+ ... AND Save value to a variable: [data][attributes][email] userEmail
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${userId}' confirmation_key
+ I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ I send a POST request: /access-tokens {"data":{"type":"access-tokens","attributes":{"username":"${userEmail}","password":"${yves_user.password_new}"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][attributes][accessToken] token
+ And Response reason should be: Created
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I get access token for the customer: ${userEmail} ${yves_user.password_new}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /customers/${userId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_customer_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] customers
+ And Response body parameter should be: [data][id] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ And Response body has correct self link internal
+
+Update_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_second_user.first_name}","lastName":"${yves_second_user.last_name}","gender":"${gender.male}","salutation":"${yves_second_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ Response status code should be: 200
+ And Response body has correct self link internal
+ And I send a GET request: /customers/${yves_user.reference}
+ Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][gender] ${gender.male}
+ [Teardown] Run Keywords I send a PATCH request: /customers/${yves_user.reference} {"data":{"type":"customers","attributes":{"firstName":"${yves_user.first_name}","lastName":"${yves_user.last_name}","gender":"${gender.female}","salutation":"${yves_user.salutation}","email":"${yves_user.email}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 200
+ ... AND Response body parameter should be: [data][attributes][salutation] ${yves_user.salutation}
+
+Get_customer_array_contains_all_available_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /customers/
+ And Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] customers
+ And Response body parameter should be: [data][0][id] ${yves_user.reference}
+ And Response body parameter should be: [data][0][attributes][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][0][attributes][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][0][attributes][email] ${yves_user.email}
+ And Response body parameter should be: [data][0][attributes][gender] ${gender.female}
+ And Response body parameter should be: [data][0][attributes][salutation] ${yves_user.salutation}
+ And Response body parameter should not be EMPTY: [data][0][attributes][createdAt]
+ And Response body parameter should not be EMPTY: [data][0][attributes][updatedAt]
+
+Delete_customer
+ [Setup] Run Keywords I send a POST request: /customers/ {"data":{"type":"customers","attributes":{"firstName":"${yves_third_user.first_name}","lastName":"${yves_third_user.last_name}","gender":"${gender.male}","salutation":"${yves_third_user.salutation}","email":"${email.name}+${random}${email.domain}","password":"${yves_user.password_new}","confirmPassword":"${yves_user.password_new}","acceptedTerms":true}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] userId
+ ... AND Save value to a variable: [data][attributes][email] userEmail
+ ... AND Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where customer_reference = '${userId}' confirmation_key
+ ... AND I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ ... AND I get access token for the customer: ${userEmail} ${yves_user.password_new}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /customers/${userId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/negative.robot b/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/negative.robot
new file mode 100644
index 0000000..37e7115
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/negative.robot
@@ -0,0 +1,352 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Add_voucher_code_to_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Add_voucher_code_to_guest_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_invalid_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_empty_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+
+Add_voucher_to_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+
+Add_invalid_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_empty_voucher_code_to_guest_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This value should not be blank.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_to_guest_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: code => This field is missing.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/fake_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_to_guest_cart_with_invalid_cart_id
+ [Setup] I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ When I send a POST request: /guest-carts/fake_guest_cart_id/vouchers {"data": {"type": "vouchers","attributes": {"code": "fake_discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_from_another_discount_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_from_another_discount_to_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_without_voucher_discount
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku}","quantity": 1}}}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_guest_user_cart_without_voucher_discount
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_availability.concrete_available_with_stock_and_never_out_of_stock_sku} 1
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_from_another_customer_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Add_voucher_code_from_another_customer_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+Add_voucher_code_to_empty_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "discount_voucher_code"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3302
+ And Response should return error message: "Cart code cant be added."
+
+
+
+#DELETE requests
+Delete_voucher_code_from_cart_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=fake_token
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Delete_voucher_code_from_cart_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I set Headers: Authorization=
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_guest_cart_without_anonymous_customer_id
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_invalid_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+
+Delete_empty_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_voucher_from_cart_without_voucher_code
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ When I send a DELETE request: /carts/${cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Delete_invalid_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 3301
+ And Response should return error message: Cart code not found in cart.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_empty_voucher_code_from_guest_user_cart
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_from_guest_user_cart_without_voucher_code
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_cart_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/fake_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_guest_user_cart_with_invalid_cart_id
+ [Setup] Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ When I send a DELETE request: /guest-carts/fake_guest_cart_id/vouchers/fake_discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Delete_voucher_code_from_another_customer_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Delete_voucher_code_from_another_customer_guest_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=fake_anonymous_customer_id
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/discount_voucher_code
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_prefix}${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/positive.robot b/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/positive.robot
new file mode 100644
index 0000000..b0e5088
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/discount_endpoints/vouchers/positive.robot
@@ -0,0 +1,158 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart promotions-discounts product-promotions marketplace-promotions-discounts
+
+*** Test Cases ***
+#POST requests
+Add_voucher_code_to_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${voucher.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_voucher_code_to_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #totals
+ And Save value to a variable: [data][attributes][totals][discountTotal] discount_total
+ And Save value to a variable: [data][attributes][totals][subtotal] subtotal
+ And Perform arithmetical calculation with two arguments: grand_total ${subtotal} - ${discount_total}
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter with rounding should be: [data][attributes][totals][grandTotal] ${grand_total}
+ And Response body parameter with rounding should be: [data][attributes][totals][priceToPay] ${grand_total}
+ #discounts
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${voucher.name}
+ And Response body parameter should be greater than: [data][attributes][discounts][0][amount] 0
+ And Response body parameter should be: [data][attributes][discounts][0][code] ${discount_voucher_code}
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 1
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+Add_voucher_code_to_cart_including_vouchers
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /carts/${cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] carts
+ And Response body parameter should be: [data][id] ${cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${voucher.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+
+Add_voucher_code_to_guest_user_cart_including_vouchers
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ When I send a POST request: /guest-carts/${guest_cart_id}/vouchers?include=vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guest_cart_id}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ #relationships
+ And Response body parameter should be: [data][relationships][vouchers][data][0][type] vouchers
+ And Response body parameter should be: [data][relationships][vouchers][data][0][id] ${discount_voucher_code}
+ #included
+ And Response body parameter should be: [included][0][type] vouchers
+ And Response body parameter should be: [included][0][id] ${discount_voucher_code}
+ And Response body parameter should be greater than: [included][0][attributes][amount] 0
+ And Response body parameter should be: [included][0][attributes][code] ${discount_voucher_code}
+ And Response body parameter should be: [included][0][attributes][discountType] voucher
+ And Response body parameter should be: [included][0][attributes][displayName] ${voucher.name}
+ And Response body parameter should be: [included][0][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [included][0][attributes][expirationDateTime]
+ And Response body parameter should be: [included][0][attributes][discountPromotionAbstractSku] None
+ And Response body parameter should be: [included][0][attributes][discountPromotionQuantity] None
+ And Response body parameter should not be EMPTY: [included][0][links][self]
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
+
+
+
+#DELETE requests
+Delete_voucher_code_from_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ ... AND I send a POST request: /carts/${cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /carts/${cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+Delete_voucher_code_from_guest_user_cart
+ [Setup] Run Keywords Create a guest cart: ${x_anonymous_prefix}${random} ${product_with_voucher_code.concrete_sku} 1
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${product_with_voucher_code.concrete_sku}","quantity": 3}}}
+ ... AND Get voucher code by discountId from Database: ${discount_voucher_type_id}
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/vouchers {"data": {"type": "vouchers","attributes": {"code": "${discount_voucher_code}"}}}
+ When I send a DELETE request: /guest-carts/${guest_cart_id}/vouchers/${discount_voucher_code}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Cleanup all items in the guest cart: ${guest_cart_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/negative.robot
new file mode 100644
index 0000000..619c5a7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-labels
+
+*** Test Cases ***
+Get_product_label_with_invalid_label_id
+ When I send a GET request: /product-labels/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_with_nonexistend_label_id
+ When I send a GET request: /product-labels/3001
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1201
+ And Response should return error message: Product label is not found.
+
+Get_product_label_without_label_id
+ When I send a GET request: /product-labels
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 1202
+ And Response should return error message: Product label id is missing.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/positive.robot
new file mode 100644
index 0000000..2f65821
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_labels/positive.robot
@@ -0,0 +1,73 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-labels alternative-products discontinued-products
+
+*** Test Cases ***
+Get_manual_product_label_by_id
+ [Documentation] https://spryker.atlassian.net/browse/CC-25716
+ [Tags] skip-due-to-issue
+ When I send a GET request: /product-labels/${label_standard.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_standard.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_standard.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should contain: [data][attributes] frontEndReference
+ And Response body has correct self link internal
+
+Get_new_product_label_by_id
+ When I send a GET request: /product-labels/${label_new.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_new.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_new.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_sale_product_label_by_id
+ When I send a GET request: /product-labels/${label_sale.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_sale.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_sale.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_discontinued_product_label_by_id
+ When I send a GET request: /product-labels/${label_discontinued.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_discontinued.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_discontinued.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
+
+Get_alternative_product_label_by_id
+ When I send a GET request: /product-labels/${label_alternative.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${label_alternative.id}
+ And Response body parameter should be: [data][type] product-labels
+ And Response body parameter should be: [data][attributes][name] ${label_alternative.name}
+ And Response body parameter should be: [data][attributes][isExclusive] False
+ And Response body parameter should not be EMPTY: [data][attributes][position]
+ And Response body parameter should not be EMPTY: [data][attributes][frontEndReference]
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/negative.robot
new file mode 100644
index 0000000..962aea5
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/negative.robot
@@ -0,0 +1,13 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_an_attribute_with_non_existent_attribute_id
+ When I send a GET request: /product-management-attributes/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4201
+ And Response should return error message: Attribute not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/positive.robot
new file mode 100644
index 0000000..e972714
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_management_attributes/positive.robot
@@ -0,0 +1,102 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product marketplace-merchant-portal-product-management marketplace-product
+
+*** Test Cases ***
+Get_all_product_management_attributes
+ When I send a GET request: /product-management-attributes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 50
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-management-attributes
+ And Response body parameter should not be EMPTY: [data][0][attributes][key]
+ And Response body parameter should not be EMPTY: [data][0][attributes][inputType]
+ And Response body parameter should not be EMPTY: [data][0][attributes][allowInput]
+ And Response body parameter should be in: [data][0][attributes][allowInput] True False
+ And Response body parameter should be in: [data][0][attributes][isSuper] True False
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys]
+ And Response body parameter should be in: [data][0][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][localizedKeys][0][translation]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values]
+ And Response body parameter should not be EMPTY: [data][0][attributes][values][0][value]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain property with value in: [data] [attributes][allowInput] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isSuper] True False
+ And Each array element of nested array should contain property with value in: [data] [attributes][localizedKeys] localeName ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][localizedKeys] translation
+ And Each array element of nested array should contain property with value NOT in: [data] [attributes][localizedKeys] translation None
+ And Each array element of array in response should contain nested property: [data] [attributes] values
+ And Each array element of array in response should contain nested property: [data] [attributes][values] value
+ And Each array element of array in response should contain nested property: [data] [attributes][values] localizedValues
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_product_management_attribute_by_id_superattribute
+ When I send a GET request: /product-management-attributes/${product_management.superattribute_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.superattribute_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][localeName]
+ And Response body parameter should not be EMPTY: [data][attributes][values][0][localizedValues][0][translation]
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_free_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_free_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] True
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
+
+Get_product_management_attribute_by_id_normal_non_editable_attribute
+ When I send a GET request: /product-management-attributes/${product_management.attribute_no_input_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][type] product-management-attributes
+ And Response body parameter should be: [data][attributes][key] ${product_management.attribute_no_input_id}
+ And Response body parameter should be: [data][attributes][inputType] text
+ And Response body parameter should be: [data][attributes][allowInput] False
+ And Response body parameter should be: [data][attributes][isSuper] False
+ And Response body parameter should not be EMPTY: [data][attributes][localizedKeys][0][translation]
+ And Response body parameter should be in: [data][attributes][localizedKeys][0][localeName] ${locale.EN.name} ${locale.DE.name}
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] translation
+ And Each array element of array in response should contain property: [data][attributes][localizedKeys] localeName
+ And Each array element of array in response should contain property: [data][attributes][values] value
+ And Each array element of array in response should contain property: [data][attributes][values] localizedValues
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] localeName
+ And Each array element of array in response should contain property: [data][attributes][values][0][localizedValues] translation
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/negative.robot
new file mode 100644
index 0000000..d87057b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/negative.robot
@@ -0,0 +1,98 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+
+*** Test Cases ***
+Get_a_review_with_non_existent_review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Product review is not found.
+
+Get_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_reviews_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_review_by_id_with_missing_abstract_product
+ When I send a GET request: /abstract-products//product-reviews/78
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_a_reviews_with_non_existent_abstract_product
+ When I send a GET request: /abstract-products/fake/product-reviews/78
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Create_a_product_review_without_token
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Create_a_product_review_with_invalid_token
+ [Setup] I set Headers: Authorization=fake
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Create_a_product_review_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-review","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Create_a_product_review_with_missing_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+
+Create_a_product_review_with_empty_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": "","nickname": "","summary": "","description": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This value should be of type numeric.
+ And Array in response should contain property with value: [errors] detail rating => This value should be greater than or equal to 1.
+ And Array in response should contain property with value: [errors] detail summary => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail nickname => This value should not be blank.
+
+Create_a_product_review_with_missing_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Array in response should contain property with value: [errors] detail rating => This field is missing.
+ And Array in response should contain property with value: [errors] detail summary => This field is missing.
+ And Array in response should contain property with value: [errors] detail nickname => This field is missing.
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/positive.robot
new file mode 100644
index 0000000..b75730f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_reviews/positive.robot
@@ -0,0 +1,89 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-rating-reviews
+
+*** Test Cases ***
+#Get Request
+Get_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_product.product_with_reviews.qty}
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Each array element of array in response should contain nested property: [data] [attributes] rating
+ And Each array element of array in response should contain nested property: [data] [attributes] nickname
+ And Each array element of array in response should contain nested property: [data] [attributes] summary
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_a_subset_of_product_reviews
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][0][attributes][rating]
+ And Response body parameter should have datatype: [data][0][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][0][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][0][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Get_product_reviews_for_product_with_no_reviews
+ When I send a GET request: /abstract-products/${product_availability.abstract_available_product_with_no_stock_and_never_out_of_stock}/product-reviews
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_product_review_by_id
+ [Setup] Run Keywords I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews
+ ... AND Save value to a variable: [data][0][id] review_id
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-reviews/${review_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${abstract_product.product_with_reviews.qty}
+ And Response body parameter should be: [data][id] ${review_id}
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should not be EMPTY: [data][attributes][rating]
+ And Response body parameter should have datatype: [data][attributes][rating] int
+ And Response body parameter should not be EMPTY: [data][attributes][nickname]
+ And Response body parameter should not be EMPTY: [data][attributes][summary]
+ And Response body parameter should not be EMPTY: [data][attributes][description]
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Create_a_product_review
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a POST request: /abstract-products/${abstract_available_product_with_stock.sku}/product-reviews {"data": {"type": "product-reviews","attributes": {"rating": ${review.default_rating},"nickname": "${yves_user.first_name}","summary": "${review.title}","description": "${review.text}"}}}
+ Then Response status code should be: 202
+ And Response reason should be: Accepted
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] review_id
+ And Response body parameter should be: [data][type] product-reviews
+ And Response body parameter should be: [data][attributes][rating] ${review.default_rating}
+ And Response body parameter should be: [data][attributes][nickname] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][summary] ${review.title}
+ And Response body parameter should be: [data][attributes][description] ${review.text}
+ And Response body has correct self link for created entity: ${review_id}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/negative.robot
new file mode 100644
index 0000000..f557502
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_a_tax_set_with_invalid_concrete_sku
+ When I send a GET request: /abstract-products/test123/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
+
+Get_a_tax_set_with_missing_sku
+ When I send a GET request: /abstract-products//product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_a_tax_set_with_non_existing_sku
+ When I send a GET request: /abstract-products/fake/product-tax-sets
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 310
+ And Response should return error message: Product tax sets not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/positive.robot
new file mode 100644
index 0000000..d9bf457
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/product_tax_sets/positive.robot
@@ -0,0 +1,22 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product tax
+
+*** Test Cases ***
+Get_product_tax sets
+ When I send a GET request: /abstract-products/${abstract_product.product_with_reviews.sku}/product-tax-sets
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should not be EMPTY: [data][0][id]
+ And Response body parameter should be: [data][0][type] product-tax-sets
+ And Response body parameter should not be EMPTY: [data][0][attributes][name]
+ And Response should contain the array larger than a certain size: [data][0][attributes][restTaxRates] 1
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] name
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] rate
+ Each array element of array in response should contain property: [data][0][attributes][restTaxRates] country
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/negative.robot
new file mode 100644
index 0000000..8a3190b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Get_related_products_without_abstract_SKU
+ When I send a GET request: /abstract-products//related-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 311
+ And Response should return error message: Abstract product sku is not specified.
+
+Get_related_products_for_nonexistent_SKU
+ When I send a GET request: /abstract-products/not_a_SKU/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
+
+Get_related_products_for_concrete_SKU
+ When I send a GET request: /abstract-products/${concrete_available_product.sku}/related-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 301
+ And Response should return error message: Abstract product is not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/positive.robot
new file mode 100644
index 0000000..5bd1d55
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/related_products/positive.robot
@@ -0,0 +1,83 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Product_has_related_products
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_related_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_related_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array of a certain size: [data][0][attributes][superAttributes] 1
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][super_attributes] 1
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 1
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributes] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeNames] brand
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Product_has_related_products_with_includes
+ [Setup] Run Keywords Trigger product labels update
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /abstract-products/${product_with_relations.has_related_products.sku}/related-products?include=product-labels
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [data][8][relationships][product-labels][data] 0
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response include should contain certain entity type: product-labels
+ And Response include element has self link: product-labels
+
+Product_has_no_related_products
+ When I send a GET request: /abstract-products/${abstract_available_product_with_stock.sku}/related-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/negative.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/negative.robot
new file mode 100644
index 0000000..270f092
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/negative.robot
@@ -0,0 +1,88 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-relations
+
+*** Test Cases ***
+#Logged in customer's cart
+Get_upselling_products_with_missing_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ When I send a GET request: /carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_invalid_token
+ [Setup] I set Headers: Content-Type=${default_header_content_type} Authorization=invalid
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Get_upselling_products_without_access_token
+ When I send a GET request: /carts//up-selling-products
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Get_upselling_products_using_cart_of_other_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+#Guest user cart
+Get_upselling_products_with_missing_guest_cart_id
+ When I send a GET request: /guest-carts//up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 104
+ And Response should return error message: Cart uuid is missing.
+
+Get_upselling_products_with_nonexistent_guest_cart_id
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+
+Get_upselling_products_with_empty_anonymous_id
+ When I send a GET request: /guest-carts/not_a_cart/up-selling-products
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 109
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Get_upselling_products_with_other_anonymous_id
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=222
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/positive.robot b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/positive.robot
new file mode 100644
index 0000000..55fc49e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/general_product_endpoints/upselling_products/positive.robot
@@ -0,0 +1,279 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product product-relations
+
+*** Test Cases ***
+Get_upselling_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+
+Get_upselling_products_plus_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: category-nodes
+ And Response include element has self link: product-reviews
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+Get_upselling_products_for_cart_containing_multiple_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${product_with_relations.has_upselling_products.concrete_sku}","quantity": 2}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+Get_upselling_products_for_cart_without_upselling_relations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+Get_upselling_products_for_empty_cart
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Find or create customer cart
+ ... AND Cleanup all items in the cart: ${cart_id}
+ When I send a GET request: /carts/${cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the cart: ${cart_id}
+
+Get_upselling_products_for_guest_cart
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body parameter should be: [data][0][id] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes]
+ And Response body parameter should be: [data][0][attributes][sku] ${product_related_product_with_upselling_relation.sku}
+ And Response body parameter should be: [data][0][attributes][averageRating] None
+ And Response body parameter should be: [data][0][attributes][reviewCount] 0
+ And Response body parameter should be: [data][0][attributes][name] ${product_related_product_with_upselling_relation.name}
+ And Response body parameter should not be EMPTY: [data][0][attributes][description]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributes]
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributesDefinition] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][superAttributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][super_attributes] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][product_concrete_ids] 0
+ And Response should contain the array of a certain size: [data][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][attributeMap][attribute_variant_map] 0
+ And Response should contain the array larger than a certain size: [data][0][attributes][metaTitle] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaKeywords]
+ And Response body parameter should not be EMPTY: [data][0][attributes][metaDescription]
+ And Response body parameter should not be EMPTY: [data][0][attributes][attributeNames]
+ And Response body parameter should not be EMPTY: [data][0][attributes][url]
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Get_upselling_products_for_guest_cart_plus_includes
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products?include=abstract-product-prices,abstract-product-image-sets,concrete-products,abstract-product-availabilities,product-labels,product-tax-sets,product-options,product-reviews,category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Response body has correct self link
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-prices][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-image-sets][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][concrete-products][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-product-availabilities][data] 1
+ And Response should contain the array of a certain size: [data][0][relationships][product-tax-sets][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][product-options][data] 1
+ And Response should contain the array larger than a certain size: [data][0][relationships][category-nodes][data] 1
+ And Response include should contain certain entity type: abstract-product-prices
+ And Response include should contain certain entity type: abstract-product-image-sets
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-product-availabilities
+ And Response include should contain certain entity type: product-labels
+ And Response include should contain certain entity type: product-tax-sets
+ And Response include should contain certain entity type: product-options
+ And Response include should contain certain entity type: product-reviews
+ And Response include should contain certain entity type: category-nodes
+ And Response include element has self link: abstract-product-prices
+ And Response include element has self link: abstract-product-image-sets
+ And Response include element has self link: concrete-products
+ And Response include element has self link: abstract-product-availabilities
+ And Response include element has self link: product-labels
+ And Response include element has self link: product-tax-sets
+ And Response include element has self link: product-options
+ And Response include element has self link: category-nodes
+ And Response include element has self link: product-reviews
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Get_upselling_products_for_guest_cart_containing_multiple_products
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${product_with_relations.has_upselling_products.concrete_sku} 2
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_of_alternative_product_with_relations_upselling.sku}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data": {"type": "guest-cart-items","attributes": {"sku": "${concrete_product.product_without_relations}","quantity": 1}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain nested property with value: [data] type abstract-products
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] sku
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][sku] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] averageRating
+ And Each array element of array in response should contain nested property: [data] [attributes] reviewCount
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][name] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] attributes
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributes] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributesDefinition
+ And Each array element of array in response should contain nested property: [data] [attributes] superAttributes
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeMap
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] super_attributes
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] product_concrete_ids
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variants
+ And Each array element of array in response should contain nested property: [data] [attributes][attributeMap] attribute_variant_map
+ And Each array element of array in response should contain nested property: [data] [attributes] metaTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] metaKeywords
+ And Each array element of array in response should contain nested property: [data] [attributes] metaDescription
+ And Each array element of array in response should contain nested property: [data] [attributes] attributeNames
+ And Each array element of array in response should contain property with value NOT in: [data] [attributes][attributeNames] None null
+ And Each array element of array in response should contain nested property: [data] [attributes] url
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
+
+Get_upselling_products_for_guest_cart_without_upselling_relations
+ [Setup] Run Keywords I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ ... AND Create a guest cart: ${random} ${concrete_product.product_without_relations} 1
+ ... AND Response status code should be: 201
+ When I send a GET request: /guest-carts/${guest_cart_id}/up-selling-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+ [Teardown] Run Keyword Cleanup all items in the guest cart: ${guest_cart_id}
diff --git a/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/negative.robot b/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/negative.robot
new file mode 100644
index 0000000..658b645
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/negative.robot
@@ -0,0 +1,307 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cart spryker-core product configurable-product product-bundles non-splittable-products proces
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+
+Add_an_item_to_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a POST request: /guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Add_item_to_guest_cart_with_wrong_type
+ [Setup] Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND I set Headers: X-Anonymous-Customer-Unique-Id=${x_anonymous_customer_unique_id}
+ When I send a POST request: /guest-cart-items {"data": {"type": "fake","attributes": {"sku": "${concrete_available_product.with_offer}","quantity": 1}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+
+Add_an_item_to_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a POST request: /guest-carts/${guest_cart_id}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_an_item_to_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a POST request: /guest-carts/guestCartId/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_an_non_existing_item_to_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"non_existing_item","quantity":"1"}}}
+ Then Array in response should contain property with value: [errors] code 102
+ And Array in response should contain property with value: [errors] code 113
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail Product "non_existing_item" not found
+ And Array in response should contain property with value: [errors] detail Cart item could not be added.
+
+Add_an_item_to_the_guest_cart_without_sku_attribute_and_quantity_attribute
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail sku => This field is missing.
+ And Array in response should contain property with value: [errors] detail quantity => This field is missing.
+
+Add_an_item_to_the_guest_cart_without_sku_and_quantity_values
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"","quantity":""}}}
+ Then Each array element of array in response should contain property with value: [errors] code 901
+ And Each array element of array in response should contain property with value: [errors] status ${422}
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail sku => This value should not be blank.
+ And Array in response should contain property with value: [errors] detail quantity => This value should not be blank.
+
+Update_an_item_quantity_at_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Update_an_item_quantity_at_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_another_anonymous
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${item_id_another_anonymous}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Update_an_item_quantity_at_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a PATCH request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Update_quantity_of_a_non_existing_item_at_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/non_existing_item {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 404
+ And Response should return error code: 103
+ And Response reason should be: Not Found
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Update_an_item_quantity_at_the_guest_cart_without_quantity_attribute
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_qty
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_qty} {"data":{"type":"guest-cart-items","attributes":{}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+
+Update_an_item_quantity_at_the_guest_cart_with_empty_quantity_value
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_qty_empty
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_qty_empty} {"data":{"type":"guest-cart-items","attributes":{"quantity":""}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+
+Update_an_item_quantity_at_the_guest_cart_with_non_numeric_quantity_value
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_qty_non_numeric
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_qty_non_numeric} {"data":{"type":"guest-cart-items","attributes":{"quantity":"test"}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type numeric.
+
+Remove_an_item_from_the_guest_cart_without_x_anonymous_customer_unique_id
+ When I send a DELETE request: /guest-carts/guestCartId/guest-cart-items/itemId
+ Then Response status code should be: 400
+ And Response should return error code: 109
+ And Response reason should be: Bad Request
+ And Response should return error message: Anonymous customer unique id is empty.
+
+Remove_a_non_existing_item_from_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/non_existing_item
+ Then Response status code should be: 404
+ And Response should return error code: 103
+ And Response reason should be: Not Found
+ And Response should return error message: Item with the given group key not found in the cart.
+
+Remove_an_item_from_the_non_existing_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ When I send a DELETE request: /guest-carts/guestCartId/guest-cart-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Remove_an_item_from_the_guest_cart_of_another_anonymous_customer
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_qty_another_customer
+ ... AND I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}1
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_qty_another_customer}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Add_a_configurable_product_to_the_cart_with_empty_quantity
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+
+ Add_a_configurable_product_to_the_cart_with_0_quantity
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":0,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_negative_quantity
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":-6,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_negative_price
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_to_the_cart_with_empty_price
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":9,"grossAmount":10,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
diff --git a/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/positive.robot b/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/positive.robot
new file mode 100644
index 0000000..95c7aea
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/guest_carts/guest_cart_items/positive.robot
@@ -0,0 +1,272 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue cart spryker-core product configurable-product product-bundles non-splittable-products prices
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+### I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+
+Add_an_item_to_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_available_product.with_offer}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Each array element of array in response should contain property: [data][attributes][discounts] displayName
+ And Each array element of array in response should contain property: [data][attributes][discounts] amount
+ And Each array element of array in response should contain property: [data][attributes][discounts] code
+ And Response body parameter should contain: [data][attributes] thresholds
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_an_item_to_the_guest_cart_with_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":"1"}}}
+ Save value to a variable: [included][0][id] sku_1_id
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][isDefault] True
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should be: [data][attributes][totals][discountTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response should contain the array of a certain size: [data][attributes][discounts] 0
+ And Response should contain the array of a certain size: [data][attributes][thresholds] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [included][0][id] ${sku_1_id}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][groupKey] ${sku_1_id}
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][productOfferReference] None
+ And Response body parameter should be: [included][0][attributes][merchantReference] None
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][taxRate]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumNetPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumGrossPrice]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumTaxAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitSubtotalAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumProductOptionPriceAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][unitPriceToPayAggregation]
+ And Response body parameter should not be EMPTY: [included][0][attributes][calculations][sumPriceToPayAggregation]
+ And Response body parameter should be: [included][0][attributes][configuredBundle] None
+ And Response body parameter should be: [included][0][attributes][configuredBundleItem] None
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response body parameter should be: [included][0][attributes][salesUnit] None
+ And Response should contain the array of a certain size: [included][0][attributes][selectedProductOptions] 0
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Add_an_item_to_the_guest_cart_with_concrete_products_and_abstract_products_includes
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=concrete-products,abstract-products {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: abstract-products
+ And Response include should contain certain entity type: guest-cart-items
+ And Response include element has self link: guest-cart-items
+ And Response include element has self link: abstract-products
+ And Response include element has self link: concrete-products
+
+Add_an_item_to_the_guest_cart_with_cart_rules_includes
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=cart-rules {"data":{"type":"guest-cart-items","attributes":{"sku":"${concrete_product_with_concrete_product_alternative.sku}","quantity": 10}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response should contain the array of a certain size: [data][relationships][cart-rules][data] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: cart-rules
+ And Response include should contain certain entity type: guest-cart-items
+ And Response include element has self link: cart-rules
+ And Response include element has self link: guest-cart-items
+
+Add_an_item_to_the_guest_cart_with_bundle_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=bundle-items,bundled-items {"data":{"type":"guest-cart-items","attributes":{"sku":"${bundled_product.concrete.product_1_sku}","quantity":"1"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should be: [included][0][attributes][sku] ${bundled_product.concrete.product_2_sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${bundled_product.concrete.product_3_sku}
+ And Response body parameter should be: [included][2][attributes][sku] ${bundled_product.concrete.product_4_sku}
+ And Response body parameter should be: [included][3][attributes][sku] ${bundled_product.concrete.product_1_sku}
+ And Response body parameter should be: [included][3][attributes][quantity] 1
+ And Response body parameter should be: [included][3][attributes][groupKey] ${bundled_product.concrete.product_1_sku}
+ And Response body parameter should be: [included][3][attributes][abstractSku] ${bundle_product.abstract.sku}
+ And Response should contain the array of a certain size: [included] 4
+ And Response include should contain certain entity type: bundled-items
+ And Response include should contain certain entity type: bundle-items
+ And Response include element has self link: bundled-items
+ And Response include element has self link: bundle-items
+
+Update_an_item_quantity_at_the_guest_cart_with_items_include
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_guest
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_guest}?include=items {"data":{"type":"guest-cart-items","attributes":{"quantity":"2"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 1
+ And Response body parameter should not be EMPTY: [data][attributes][discounts]
+ And Each array element of array in response should contain property: [data][attributes][discounts] displayName
+ And Each array element of array in response should contain property: [data][attributes][discounts] amount
+ And Each array element of array in response should contain property: [data][attributes][discounts] code
+ And Response body parameter should contain: [data][attributes] thresholds
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should contain: [included][0][id] ${concrete_available_product.with_offer}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Remove_an_item_from_the_guest_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_available_product.with_offer} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ ... AND Save value to a variable: [included][0][id] item_id_guest1
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/${item_id_guest1}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+
+
+
+Add_a_configurable_product_to_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][currency] ${currency.eur.code}
+ And Response body parameter should be: [included][0][type] guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][priceToPay] 0
+ And Response body parameter should be: [data][attributes][discounts][0][displayName] ${discount_1.name}
+ And Response body parameter should not be EMPTY: [data][attributes][discounts][0][amount]
+ And Response body parameter should be: [data][attributes][discounts][0][code] None
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+
+Change_configuration_and_quantity_in_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":1,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [included][0][id] item_uid
+ And Save value to a variable: [included][0][attributes][calculations][sumPriceToPayAggregation] item_total_price
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][configuration] {\"time_of_day\":\"4\"}
+ When I send a PATCH request: /guest-carts/${guestCartId}/guest-cart-items/${item_uid}?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${guestCartId}
+ And Response body parameter should be: [data][type] guest-carts
+ And Response body parameter should be: [included][0][id] ${item_uid}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][amount] None
+ And Response body parameter should be: [included][0][attributes][calculations][sumPriceToPayAggregation] 76504
+ And Response body parameter should not be EMPTY: [data][links][self]
+
+Delete_configurable_product_item_form_the_cart
+ [Setup] I set Headers: Content-Type=${default_header_content_type} X-Anonymous-Customer-Unique-Id=${random}
+ Run Keywords Create a guest cart: ${random} ${concrete_product_with_concrete_product_alternative.sku} 1
+ ... AND Save value to a variable: [data][id] guestCartId
+ ... AND Cleanup All Items In The Guest Cart: ${guest_cart_id}
+ When I send a POST request: /guest-carts/${guestCartId}/guest-cart-items?include=items {"data":{"type":"guest-cart-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Save value to a variable: [included][0][id] item_id2
+ When I send a DELETE request: /guest-carts/${guestCartId}/guest-cart-items/${item_id2}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /guest-carts/${guestCartId}?include=guest-cart-items
+ And Response body parameter should be: [data][attributes][totals][grandTotal] 0
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/negative.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/negative.robot
new file mode 100644
index 0000000..0b91899
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/negative.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+
+*** Test Cases ***
+Retrieves_merchant_addresses_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-addresses
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-addresses
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/positive.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/positive.robot
new file mode 100644
index 0000000..c0bed05
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_addresses/positive.robot
@@ -0,0 +1,61 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core
+
+*** Test Cases ***
+Retrieves_merchant_addresses
+ When I send a GET request: /merchants/${merchants.sony_experts.merchant_reference}/merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchants.sony_experts.merchant_reference}
+ And Response body parameter should be: [data][0][type] merchant-addresses
+ And Response body parameter should be: [data][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [data][0][attributes][addresses][0][city] ${merchants.sony_experts.addresses.city_munchen}
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-addresses
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address2
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [data] [attributes][addresses] longitude
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+Retrieves_merchant_with_include_merchant_addresses
+ When I send a GET request: /merchants/${merchants.sony_experts.merchant_reference}?include=merchant-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchants.sony_experts.merchant_reference}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should have datatype: [data][relationships] dict
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-addresses]
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-addresses][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-addresses
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] countryName
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address1
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] address3
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] city
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] zipCode
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] latitude
+ And Each array element of array in response should contain nested property: [included] [attributes][addresses] longitude
+ And Response body parameter should be: [included][0][attributes][addresses][0][countryName] ${default.country}
+ And Response body parameter should be: [included][0][attributes][addresses][0][city] ${merchants.sony_experts.addresses.city_munchen}
+ And Response body parameter should be: [included][0][attributes][addresses][0][address1] ${merchants.sony_experts.addresses.address1}
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/negative.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/negative.robot
new file mode 100644
index 0000000..b20b119
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours_by_non_exist_merchant_id
+ When I send a GET request: /merchants/NonExistId/merchant-opening-hours
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
+
+
+Retrieves_merchant_addresses_witout_pass_merchant_id
+ When I send a GET request: /merchants//merchant-opening-hours
+ Then Response status code should be: 400
+ And Response should return error code: 3502
+ And Response should return error message: Merchant identifier is not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/positive.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/positive.robot
new file mode 100644
index 0000000..c81fcbd
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchant_opening_hours/positive.robot
@@ -0,0 +1,62 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant marketplace-merchantportal-core merchant-opening-hours
+
+*** Test Cases ***
+Retrieves_merchant_opening_hours
+ When I send a GET request: /merchants/${merchants.sony_experts.merchant_reference}/merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][id] ${merchants.sony_experts.merchant_reference}
+ And Response body parameter should be: [data][0][type] merchant-opening-hours
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchant-opening-hours
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][weekdaySchedule] list
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][dateSchedule] list
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [data] [attributes][dateSchedule] noteGlossaryKey
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_merchant_with_include_merchant_opening_hours
+ When I send a GET request: /merchants/${merchants.sony_experts.merchant_reference}?include=merchant-opening-hours
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][id] ${merchants.sony_experts.merchant_reference}
+ And Response should contain the array of a certain size: [included][0][attributes][weekdaySchedule] 8
+ And Response should contain the array of a certain size: [included][0][attributes][dateSchedule] 154
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchant-opening-hours]
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] type
+ And Each array element of array in response should contain property: [data][relationships][merchant-opening-hours][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain property with value: [included] type merchant-opening-hours
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] day
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][weekdaySchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] date
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeFrom
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] timeTo
+ And Each array element of array in response should contain nested property: [included] [attributes][dateSchedule] noteGlossaryKey
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][day] MONDAY
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeFrom] 07:00:00.000000
+ And Response body parameter should be: [included][0][attributes][weekdaySchedule][0][timeTo] 13:00:00.000000
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][date] 2024-01-01
+ And Response body parameter should be: [included][0][attributes][dateSchedule][0][noteGlossaryKey] "New Years Day"
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/negative.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/negative.robot
new file mode 100644
index 0000000..7c7135b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/negative.robot
@@ -0,0 +1,12 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieves_merchant_by_non_exist_id
+ When I send a GET request: /merchants/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 3501
+ And Response should return error message: Merchant not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/positive.robot b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/positive.robot
new file mode 100644
index 0000000..837b3b0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/merchant_endpoints/merchants/positive.robot
@@ -0,0 +1,67 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieves_list_of_merchants
+ When I send a GET request: /merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type merchants
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantName
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonRole
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonTitle
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonFirstName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonLastName
+ And Each array element of array in response should contain nested property: [data] [attributes] contactPersonPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] logoUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] publicEmail
+ And Each array element of array in response should contain nested property: [data] [attributes] publicPhone
+ And Each array element of array in response should contain nested property: [data] [attributes] description
+ And Each array element of array in response should contain nested property: [data] [attributes] bannerUrl
+ And Each array element of array in response should contain nested property: [data] [attributes] deliveryTime
+ And Each array element of array in response should contain nested property: [data] [attributes] faxNumber
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] terms
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] cancellationPolicy
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] imprint
+ And Each array element of array in response should contain nested property: [data] [attributes][legalInformation] dataPrivacy
+ And Each array element of array in response should contain nested property: [data] [attributes] categories
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+
+
+Retrieves_a_merchant_by_id
+ When I send a GET request: /merchants/${merchants.sony_experts.merchant_reference}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should not be EMPTY: [data][type]
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should be: [data][id] ${merchants.sony_experts.merchant_reference}
+ And Response body parameter should be: [data][type] merchants
+ And Response body parameter should be: [data][attributes][merchantName] ${merchants.sony_experts.merchant_name}
+ And Response body parameter should be: [data][attributes][merchantUrl] ${merchants.sony_experts.merchant_url}
+ And Response body parameter should be: [data][attributes][contactPersonRole] ${merchants.sony_experts.contact_person_role}
+ And Response body parameter should be: [data][attributes][contactPersonTitle] ${merchants.sony_experts.contact_person_title}
+ And Response body parameter should be: [data][attributes][contactPersonFirstName] ${merchants.sony_experts.contact_person_first_name}
+ And Response body parameter should be: [data][attributes][contactPersonLastName] ${merchants.sony_experts.contact_person_last_name}
+ And Response body parameter should be: [data][attributes][contactPersonPhone] ${merchants.sony_experts.contact_person_phone}
+ And Response body parameter should be: [data][attributes][publicEmail] ${merchants.sony_experts.public_email}
+ And Response body parameter should be: [data][attributes][publicPhone] ${merchants.sony_experts.public_phone}
+ And Response body parameter should be: [data][attributes][description] ${merchants.sony_experts.description}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should not be EMPTY: [data][attributes][logoUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][bannerUrl]
+ And Response body parameter should not be EMPTY: [data][attributes][deliveryTime]
+ And Response body parameter should not be EMPTY: [data][attributes][faxNumber]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][terms]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][cancellationPolicy]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][imprint]
+ And Response body parameter should not be EMPTY: [data][attributes][legalInformation][dataPrivacy]
+ And Response body parameter should have datatype: [data][attributes][categories] list
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/negative.robot b/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/negative.robot
new file mode 100644
index 0000000..ee19671
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/negative.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue navigation spryker-core
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+Get_navigations_by_non_exist_id
+ When I send a GET request: /navigations/testNonExistNavigations
+ Then Response status code should be: 404
+ And Response should return error code: 1601
+ And Response should return error message: Navigation not found.
+
+Get_absent_navigations
+ When I send a GET request: /navigations
+ Then Response status code should be: 400
+ And Response should return error code: 1602
+ And Response should return error message: Navigation id not specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/positive.robot b/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/positive.robot
new file mode 100644
index 0000000..81839e3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/navigation_endpoints/navigations/positive.robot
@@ -0,0 +1,71 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core navigation category-management merchant-category
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+To_retrieve_a_navigation_tree
+ When I send a GET request: /navigations/MAIN_NAVIGATION
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Body parameter should have datatype: [data][attributes][name] str
+ And Response Body parameter should have datatype: [data][attributes][isActive] bool
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes] children
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][nodeType] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][title] str
+ And Response Body parameter should have datatype: [data][attributes][nodes][0][children] list
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][nodeType]
+ And Response body parameter should not be EMPTY: [data][attributes][nodes][0][title]
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] resourceId
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] nodeType
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] isActive
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] title
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] url
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] cssClass
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validFrom
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] validTo
+ And Each Array Element Of Array In Response Should Contain Property: [data][attributes][nodes][0][children] children
+ And Response body has correct self link internal
+
+Get_navigation_tree_using_valid_navigation_key_with_category_nodes_included
+ When I send a GET request: /navigations/MAIN_NAVIGATION?include=category-nodes
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] navigations
+ And Response body parameter should be: [data][id] MAIN_NAVIGATION
+ And Response Should Contain The Array Larger Than a Certain Size: [included] 0
+ And Response Should Contain The Array Larger Than a Certain Size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][category-nodes]
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] type
+ And Each Array Element Of Array In Response Should Contain Property: [data][relationships][category-nodes][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each Array Element Of Array In Response Should Contain Property With Value: [included] type category-nodes
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes nodeId
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes name
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaTitle
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaKeywords
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes metaDescription
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes isActive
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes order
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes url
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes children
+ And Each Array Element Of Array In Response Should Contain Nested Property: [included] attributes parents
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/negative.robot b/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/negative.robot
new file mode 100644
index 0000000..a388b4d
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/negative.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue order-management marketplace-order-management spryker-core customer-access
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#GET requests
+Get_order_by_order_id_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_order_by_order_id_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /orders/order_id
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_order_with_invalid_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/fake_order_id
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+
+Get_order_by_order_id_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_another_customer
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_another_customer}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ ... AND I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find order by the given order reference"
+ And Response should return error code: 801
+
+Get_customer_orders_list_with_invalid_access_token
+ [Setup] I set Headers: Authorization=fake_token
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_customer_orders_list_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_customer_orders_list_with_invalid_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/yves_user.reference/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_without_customer_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers//orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
+
+Get_customer_orders_list_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /customers/${yves_second_user.reference}/orders
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Unauthorized request.
+ And Response should return error code: 802
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/positive.robot b/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/positive.robot
new file mode 100644
index 0000000..f887545
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/order_endpoints/orders/positive.robot
@@ -0,0 +1,799 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue cart checkout order-management marketplace-order-management marketplace-product merchant product product-bundles marketplace-packaging-units measurement-units packaging-units non-splittable-products shipment marketplace-shipment configurable-bundle configurable-product gift-cards spryker-core customer-access
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#GET requests
+Get_order_by_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity":1,"merchantReference":"${merchants.spryker.merchant_reference}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_regular_order
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_regular_order}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountFullAggregation]
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be: [data][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [data][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_bundle_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${bundled_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_bundle_product
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_bundle_product}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Each array element of array in response should contain property with value: [data][attributes][items] bundleItemIdentifier ${None}
+ And Each array element of array in response should contain property: [data][attributes][items] relatedBundleItemIdentifier
+ And Response body parameter should be: [data][attributes][items][0][name] ${bundled_product.concrete.product_2_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${bundled_product.concrete.product_2_sku}
+ And Response body parameter should be: [data][attributes][items][1][name] ${bundled_product.concrete.product_3_name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${bundled_product.concrete.product_3_sku}
+ And Response body parameter should be: [data][attributes][items][2][name] ${bundled_product.concrete.product_4_name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${bundled_product.concrete.product_4_sku}
+ #bundleItems
+ And Response body parameter should be: [data][attributes][bundleItems][0][name] ${bundled_product.concrete.product_1_name}
+ And Response body parameter should be: [data][attributes][bundleItems][0][sku] ${bundled_product.concrete.product_1_sku}
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumGrossPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRate] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPrice] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumTaxAmountFullAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][refundableAmount] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][canceledAmount] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumProductOptionPriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][unitExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][sumExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumDiscountAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxRateAverageAggregation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][orderReference] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][uuid] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][isReturnable] None
+ And Response body parameter should be: [data][attributes][bundleItems][0][idShipment] None
+ And Response body parameter should be greater than: [data][attributes][bundleItems][0][bundleItemIdentifier] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][metadata][superAttributes] 0
+ And Response body parameter should not be EMPTY: [data][attributes][bundleItems][0][metadata][image]
+ And Response body parameter should be: [data][attributes][bundleItems][0][salesUnit] None
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][calculatedDiscounts] 0
+ And Response should contain the array of a certain size: [data][attributes][bundleItems][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][bundleItems][0][amount] None
+ And Response body has correct self link internal
+
+Get_order_by_order_id_with_sales_unit
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a GET request: /concrete-products/${concrete_product.random_weight.sku}?include=sales-units
+ ... AND Save value to a variable: [included][0][id] sales_unit_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+ ... AND Save value to a variable: [included][0][id] item_id_sales_unit
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_sales_unit}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${concrete_product.random_weight.name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${concrete_product.random_weight.sku}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items] 1
+ And Response body parameter should be: [data][attributes][items][0][salesUnit][conversion] ${concrete_product.random_weight.conversion}
+ And Response body parameter should be: [data][attributes][items][0][salesUnit][precision] ${concrete_product.random_weight.precision}
+ And Response body parameter should be: [data][attributes][items][0][salesUnit][productMeasurementUnit][name] ${packaging_unit.m_name}
+ And Response body parameter should be: [data][attributes][items][0][salesUnit][productMeasurementUnit][code] ${packaging_unit.m}
+ And Response body parameter should be: [data][attributes][items][0][amount] ${concrete_product.random_weight.amount}
+
+Get_order_by_order_id_with_different_items_and_quantity
+ [Documentation] https://spryker.atlassian.net/browse/CC-25733
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_dif_items1
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_alternative.sku}","quantity": 2}}}
+ ... AND Save value to a variable: [included][1][id] item_id_dif_items2
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name_1}"}],"shipments": [{"items": ["${item_id_dif_items1}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "2025-09-29"},{"items": ["${item_id_dif_items2}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate":"2025-09-29" }]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 3
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be: [data][attributes][items][2][name] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][attributes][items][2][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][items][2][quantity] 1
+
+Get_order_by_order_id_with_nonsplit_item
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 5}}}
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${product_availability.concrete_available_with_stock_and_never_out_of_stock}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #items
+ And Response should contain the array of a certain size: [data][attributes][items] 5
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+
+Get_order_by_order_id_with_split_shipment_&_include
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_split_ship1
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product_with_alternative.sku}","quantity": 1}}}
+ ... AND Save value to a variable: [included][1][id] item_id_split_ship2
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"salutation": "${yves_user.salutation}","email": "${yves_user.email}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentMethodName": "${payment.method_name}","paymentProviderName": "${payment.provider_name_1}"}],"shipments": [{"items": ["${item_id_split_ship1}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}"},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"},{"items": ["${item_id_split_ship2}"],"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${changed.address1}","address2": "${changed.address2}","address3": "${changed.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${changed.phone}","isDefaultBilling": false,"isDefaultShipping": false},"idShipmentMethod": 1,"requestedDeliveryDate": "${shipment.delivery_date}"}]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}?include=order-shipments
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shippingAddress] None
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][1][name] ${concrete_product_with_alternative.name}
+ And Response body parameter should be: [data][attributes][items][1][sku] ${concrete_product_with_alternative.sku}
+ And Response body parameter should be: [data][attributes][items][1][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][1][idShipment] 0
+ And Response should contain the array of a certain size: [data][attributes][shipments] 0
+ And Response should contain certain number of values: [data][attributes][expenses] idShipment 2
+ And Response body has correct self link internal
+ And Each array element of array in response should contain property with value: [data][relationships][order-shipments][data] type order-shipments
+ And Each array element of array in response should contain property: [data][relationships][order-shipments][data] id
+ And Response should contain the array of a certain size: [included] 2
+ #included 1
+ And Response body parameter should be: [included][0][type] order-shipments
+ And Response body parameter should be greater than: [included][0][id] 0
+ And Response body parameter should not be EMPTY: [included][0][attributes][itemUuids][0]
+ And Response body parameter should be: [included][0][attributes][methodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][0][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][0][attributes][requestedDeliveryDate] ${shipment.delivery_date}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][0][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][0][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][0][links]
+ #included 2
+ And Response body parameter should be: [included][1][type] order-shipments
+ And Response body parameter should be greater than: [included][1][id] 0
+ And Response body parameter should not be EMPTY: [included][1][attributes][itemUuids][0]
+ And Response body parameter should be: [included][1][attributes][methodName] ${shipment.method_name_1}
+ And Response body parameter should be: [included][1][attributes][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [included][1][attributes][requestedDeliveryDate] ${shipment.delivery_date}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][salutation] ${yves_user.salutation}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][firstName] ${yves_user.first_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][lastName] ${yves_user.last_name}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address1] ${changed.address1}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address2] ${changed.address2}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][address3] ${changed.address3}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][phone] ${changed.phone}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][description] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][email] None
+ And Response body parameter should be: [included][1][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [included][1][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ And Response body parameter should not be EMPTY: [included][1][links]
+
+Get_customer_orders_list_without_order_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_no_order_id
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_no_order_id}"]}}}
+ When I send a GET request: /orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_customer_orders_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_no_order_list
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_no_order_list}"]}}}
+ When I send a GET request: /customers/${yves_user.reference}/orders
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type orders
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain property: [data] links
+ And Response body has correct self link
+
+Get_customer_orders_list_without_order_id_with_pagination
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_with_pagination
+ ... AND I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_with_pagination}"]}}}
+ ... AND I send a GET request: /orders
+ ... AND Save value to a variable: [data][2][id] order_id
+ When I send a GET request: /customers/${yves_user.reference}/orders?page[offset]=2&page[limit]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Response body parameter should be: [data][0][type] orders
+ And Response body parameter should be: [data][0][id] ${order_id}
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] currencyIsoCode
+ And Each array element of array in response should contain nested property: [data] [attributes] priceMode
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] taxTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] subtotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] grandTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] canceledTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][totals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Get_order_with_configurable_bundle
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND Response status code should be: 201
+ ... AND I send a POST request: /carts/${cart_id}/configured-bundles?include=items {"data": {"type": "configured-bundles","attributes": {"quantity": ${configured_bundle_quantity},"templateUuid": "${configurable_bundle_template_2_uuid}","items": [{"sku": "${configurable_bundle_fifth_slot_item_sku}","quantity": 2,"slotUuid": "${configurable_bundle_slot_5_uuid}"}]}}}
+ ... AND Save value to a variable: [included][0][id] item_id_config_bundle
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_config_bundle}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${concrete.available_product.with_stock.name2}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${concrete.available_product.with_stock.sku2}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][taxRate] 0.00
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountFullAggregation]
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxRateAverageAggregation] 0.00
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][productOfferReference] None
+ And Response body parameter should contain: [data][attributes][items][0][salesOrderConfiguredBundle] idSalesOrderConfiguredBundle
+ And Response body parameter should be: [data][attributes][items][0][salesOrderConfiguredBundle][configurableBundleTemplateUuid] ${configurable_bundle_template_2_uuid}
+ And Response body parameter should be: [data][attributes][items][0][salesOrderConfiguredBundle][name] ${configurable_bundle_template_name_2}
+ And Response body parameter should be: [data][attributes][items][0][salesOrderConfiguredBundle][quantity] 1
+ And Response body parameter should contain: [data][attributes][items][0][salesOrderConfiguredBundleItem] idSalesOrderConfiguredBundle
+ And Response body parameter should be: [data][attributes][items][0][salesOrderConfiguredBundleItem][configurableBundleTemplateSlotUuid] ${configurable_bundle_slot_5_uuid}
+ And Response should contain the array of a certain size: [data][attributes][items][0][metadata][superAttributes] 2
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be: [data][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [data][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be greater than: [data][attributes][payments][0][amount] 0
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
+
+Get_order_with_gift_card
+ [Tags] skip-due-to-issue
+ [Documentation] bug https://spryker.atlassian.net/browse/CC-21301, https://spryker.atlassian.net/browse/CC-25733
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${product_availability.concrete_available_with_stock_and_never_out_of_stock}","quantity": 1}}}
+ ... AND Save value to a variable: [included][0][id] item_id_gift_card
+ ... AND Create giftcode in Database: order_${random} ${gift_card.amount}
+ ... AND I send a POST request: /carts/${cart_id}/cart-codes?include=vouchers,gift-cards {"data": {"type": "cart-codes","attributes": {"code": "order_${random}"}}}
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_second_user.email}","salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_second_user.salutation}","firstName": "${yves_second_user.first_name}","lastName": "${yves_second_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_gift_card}"]}}}
+ ... AND Save value to a variable: [data][attributes][orderReference] order_id
+ When I send a GET request: /orders/${order_id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] orders
+ And Response body parameter should be: [data][id] ${order_id}
+ And Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ And Response body parameter should be: [data][attributes][currencyIsoCode] ${currency.eur.code}
+ And Response body parameter should be: [data][attributes][priceMode] ${mode.gross}
+ #totals
+ And Response body parameter should be greater than: [data][attributes][totals][expenseTotal] 0
+ And Response body parameter should not be EMPTY: [data][attributes][totals][discountTotal]
+ And Response body parameter should be greater than: [data][attributes][totals][taxTotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][subtotal] 0
+ And Response body parameter should be greater than: [data][attributes][totals][grandTotal] 0
+ And Response body parameter should be: [data][attributes][totals][canceledTotal] 0
+ And Response body parameter should be: [data][attributes][totals][remunerationTotal] 0
+ #billingAddress
+ And Response body parameter should be: [data][attributes][billingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][billingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][billingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][billingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][billingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][billingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][billingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][billingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][billingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][billingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][billingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][billingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][billingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][billingAddress][description] None
+ And Response body parameter should be: [data][attributes][billingAddress][comment] None
+ And Response body parameter should be: [data][attributes][billingAddress][email] None
+ And Response body parameter should be: [data][attributes][billingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][billingAddress][iso2Code] ${default.iso2Code}
+ #shippingAddress
+ And Response body parameter should be: [data][attributes][shippingAddress][salutation] ${yves_second_user.salutation}
+ And Response body parameter should be: [data][attributes][shippingAddress][firstName] ${yves_second_user.first_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][middleName] None
+ And Response body parameter should be: [data][attributes][shippingAddress][lastName] ${yves_second_user.last_name}
+ And Response body parameter should be: [data][attributes][shippingAddress][address1] ${default.address1}
+ And Response body parameter should be: [data][attributes][shippingAddress][address2] ${default.address2}
+ And Response body parameter should be: [data][attributes][shippingAddress][address3] ${default.address3}
+ And Response body parameter should be: [data][attributes][shippingAddress][company] ${default.company}
+ And Response body parameter should be: [data][attributes][shippingAddress][city] ${default.city}
+ And Response body parameter should be: [data][attributes][shippingAddress][zipCode] ${default.zipCode}
+ And Response body parameter should be: [data][attributes][shippingAddress][poBox] None
+ And Response body parameter should be: [data][attributes][shippingAddress][phone] ${default.phone}
+ And Response body parameter should be: [data][attributes][shippingAddress][cellPhone] None
+ And Response body parameter should be: [data][attributes][shippingAddress][description] None
+ And Response body parameter should be: [data][attributes][shippingAddress][comment] None
+ And Response body parameter should be: [data][attributes][shippingAddress][email] None
+ And Response body parameter should be: [data][attributes][shippingAddress][country] ${default.country}
+ And Response body parameter should be: [data][attributes][shippingAddress][iso2Code] ${default.iso2Code}
+ #items
+ And Response body parameter should be: [data][attributes][items][0][name] ${product_availability.concrete_available_with_stock_and_never_out_of_stock_name}
+ And Response body parameter should be: [data][attributes][items][0][sku] ${product_availability.concrete_available_with_stock_and_never_out_of_stock}
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][quantity] 1
+ And Response body parameter should be greater than: [data][attributes][items][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][items][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][items][0][sumNetPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPrice] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumTaxAmountFullAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][refundableAmount] 0
+ And Response body parameter should be: [data][attributes][items][0][canceledAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumSubtotalAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][unitSubtotalAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumProductOptionPriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][unitExpensePriceAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][sumExpensePriceAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][unitDiscountAmountFullAggregation]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][sumDiscountAmountFullAggregation]
+ And Response body parameter should be greater than: [data][attributes][items][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][taxRateAverageAggregation] 0
+ And Response body parameter should be: [data][attributes][items][0][taxAmountAfterCancellation] None
+ And Response body parameter should be: [data][attributes][items][0][orderReference] None
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][uuid]
+ And Response body parameter should be: [data][attributes][items][0][isReturnable] False
+ And Response body parameter should be greater than: [data][attributes][items][0][idShipment] 0
+ And Response body parameter should be: [data][attributes][items][0][bundleItemIdentifier] None
+ And Response body parameter should be: [data][attributes][items][0][relatedBundleItemIdentifier] None
+ And Response should contain the array of a certain size: [data][attributes][items][0][metadata][superAttributes] 1
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][metadata][image]
+ And Response body parameter should be: [data][attributes][items][0][salesUnit] None
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][unitAmount] 0
+ And Response body parameter should be greater than: [data][attributes][items][0][calculatedDiscounts][0][sumAmount] 0
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][displayName]
+ And Response body parameter should not be EMPTY: [data][attributes][items][0][calculatedDiscounts][0][description]
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][voucherCode] None
+ And Response body parameter should be: [data][attributes][items][0][calculatedDiscounts][0][quantity] 1
+ And Response should contain the array of a certain size: [data][attributes][items][0][productOptions] 0
+ And Response body parameter should be: [data][attributes][items][0][amount] None
+ #expenses
+ And Response body parameter should be: [data][attributes][expenses][0][type] SHIPMENT_EXPENSE_TYPE
+ And Response body parameter should be: [data][attributes][expenses][0][name] ${shipment.method_name_1}
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumGrossPrice] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][taxRate] 0
+ And Response body parameter should be: [data][attributes][expenses][0][unitNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][sumNetPrice] 0
+ And Response body parameter should be: [data][attributes][expenses][0][canceledAmount] None
+ And Response body parameter should be: [data][attributes][expenses][0][unitDiscountAmountAggregation] None
+ And Response body parameter should be: [data][attributes][expenses][0][sumDiscountAmountAggregation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitTaxAmount] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumTaxAmount] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][unitPriceToPayAggregation] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][sumPriceToPayAggregation] 0
+ And Response body parameter should be: [data][attributes][expenses][0][taxAmountAfterCancellation] None
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idShipment] 0
+ And Response body parameter should be greater than: [data][attributes][expenses][0][idSalesExpense] 0
+ #payments
+ And Response body parameter should be: [data][attributes][payments][0][amount] ${gift_card.amount}
+ And Response body parameter should be: [data][attributes][payments][0][paymentProvider] ${gift_card.paymentProvider}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][0][paymentMethod] ${gift_card.paymentMethod}
+ And Response body parameter should be greater than: [data][attributes][payments][1][amount] 0
+ And Response body parameter should be: [data][attributes][payments][1][paymentProvider] ${payment.provider_name_1}
+ And Response body case-insensitive parameter should be: [data][attributes][payments][1][paymentMethod] ${payment.method_name}
+ #shipments
+ And Response body parameter should be: [data][attributes][shipments][0][shipmentMethodName] ${shipment.method_name_1}
+ And Response body parameter should be: [data][attributes][shipments][0][carrierName] ${shipment.carrier_name}
+ And Response body parameter should be: [data][attributes][shipments][0][deliveryTime] None
+ And Response body parameter should be greater than: [data][attributes][shipments][0][defaultGrossPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][defaultNetPrice] 0
+ And Response body parameter should be: [data][attributes][shipments][0][currencyIsoCode] ${currency.eur.code}
+ #calculatedDiscounts
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] unitAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] sumAmount
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] displayName
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] description
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] voucherCode
+ And Response body parameter should contain: [data][attributes][calculatedDiscounts] quantity
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/negative.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
new file mode 100644
index 0000000..a591614
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/negative.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+Get_product_offer_availabilities_without_offerId
+ When I send a GET request: /product-offers//product-offer-availabilities
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_product_offer_availabilities_with_invalid_offerId
+ When I send a GET request: /product-offers/InvalidOfferId/product-offer-availabilities
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer was not found.
+
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/positive.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
new file mode 100644
index 0000000..c706fe6
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_availabilities/positive.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product
+
+*** Test Cases ***
+Get_product_offer_availabilities
+ I send a GET request: /concrete-products/${concrete_product.product_with_concrete_offers.sku}/product-offers
+ AND Save value to a variable: [data][0][id] offerId
+ When I send a GET request: /product-offers/${offerId}/product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type product-offer-availabilities
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] isNeverOutOfStock
+ And Each array element of array in response should contain nested property: [data] [attributes] availability
+ And Each array element of array in response should contain nested property: [data] [attributes] quantity
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][isNeverOutOfStock] bool
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][availability] bool
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][quantity] str
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/negative.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/negative.robot
new file mode 100644
index 0000000..3432588
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/negative.robot
@@ -0,0 +1,55 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_product_offer_prices_without_offer_id
+ When I send a GET request: /product-offers//product-offer-prices
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_product_offers_price_without_complete_url
+ When I send a GET request: /product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 3702
+ And Response reason should be: Bad Request
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_concrete_product_offers_price
+ When I send a GET request: /concrete-products/123456789/product-offers?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_product_offer_with_volume_prices_included_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_denied_product_offer
+ When I send a GET request: /product-offers/${denied_offer_with_volume_price}/product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+
+Get_product_offer_prices_with_invaild_offer_id
+ When I send a GET request: /product-offers/test/product-offer-prices
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/positive.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/positive.robot
new file mode 100644
index 0000000..0ebf8f8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offer_prices/positive.robot
@@ -0,0 +1,134 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Retrieve_prices_of_a_product_offer
+ When I send a GET request: /product-offers/${active_offer}/product-offer-prices
+ Then Response reason should be: OK
+ And Response status code should be: 200
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][id] ${active_offer}
+ And Response body parameter should be: [data][0][attributes][price] ${active_offer_price}
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices]
+ And Response body has correct self link
+
+Get_concrete_product_without_offers_prices
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/product-offers?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_all_concrete_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /concrete-products/${abstract_product.product_with_concrete_offers.concrete_sku}/product-offers?include=product-offer-prices,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${active_offer_2}
+ And Response body parameter should be: [data][0][type] product-offers
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${merchant_sony_experts_id}
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should contain: [data][0][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 4
+ And Response should contain the array of a certain size: [data][0][relationships] 2
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: merchants
+ And Response body has correct self link
+
+Get_all_product_offer_info_with_product_offer_prices_and_merchants_included
+ When I send a GET request: /product-offers/${offer_with_merchant_sku}?include=product-offer-prices,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_merchant_sku}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.spryker.merchant_reference}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantSku]
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array of a certain size: [data][relationships] 2
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: merchants
+
+Get_product_offer_price_without_volume_prices
+ When I send a GET request: /product-offers/${offer_without_volume_price}/product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_without_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 0
+ And Response body parameter should not be EMPTY: [data][0][attributes][price]
+ And Response body parameter should not be EMPTY: [data][0][attributes][prices]
+
+Get_product_offer_price_with_gross_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price_gross_net_prices}/product-offer-prices?priceMode=${mode.gross}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price_gross_net_prices}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][grossAmount] 0
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_price_with_net_eur_volume_prices
+ When I send a GET request: /product-offers/${offer_with_volume_price_gross_net_prices}/product-offer-prices?priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price_gross_net_prices}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][netAmount] 0
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][volumePrices] 3
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][grossAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][netAmount] int
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][prices][0][volumePrices][0][quantity] int
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_price_with_gross_chf
+ When I send a GET request: /product-offers/${offer_with_volume_price_gross_net_prices}/product-offer-prices?currency=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price_gross_net_prices}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][grossAmount] 1
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Get_product_offer_price_with_net_chf
+ When I send a GET request: /product-offers/${offer_with_volume_price}/product-offer-prices?currency=${currency.chf.code}&priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${offer_with_volume_price}
+ And Response body parameter should be: [data][0][type] product-offer-prices
+ And Response body parameter should be: [data][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [data][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [data][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [data][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/negative.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/negative.robot
new file mode 100644
index 0000000..8bf0258
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/negative.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer marketplace-product-offer-prices prices marketplace-product
+
+*** Test Cases ***
+Get_product_offers_without_product_offer_id
+ When I send a GET request: /product-offers/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3702
+ And Response should return error message: Product offer ID is not specified.
+
+Get_not_existing_concrete_product_offers
+ When I send a GET request: /concrete-products/123456789/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_product_offer_with_volume_prices_included_for_inactive_product_offer
+ When I send a GET request: /product-offers/${inactive_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_waiting_for_approval_product_offer
+ When I send a GET request: /product-offers/${waiting_for_approval_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_volume_prices_included_for_denied_product_offer
+ When I send a GET request: /product-offers/${denied_offer_with_volume_price}?include=product-offer-prices
+ Then Response status code should be: 404
+ And Response should return error code: 3701
+ And Response reason should be: Not Found
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_invaild_offer_id
+ When I send a GET request: /product-offers/test
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3701
+ And Response should return error message: Product offer not found.
+
+Get_product_offer_with_empty_product_id
+ When I send a GET request: /concrete-products//product-offers
+ Then Response status code should be: 400
+ And Response should return error code: 312
+ And Response reason should be: Bad Request
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/positive.robot b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/positive.robot
new file mode 100644
index 0000000..13a3be2
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/product_offer_endpoints/product_offers/positive.robot
@@ -0,0 +1,189 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue product marketplace-product-offer product-offer-shipment marketplace-product-offer-prices prices marketplace-product merchant marketplace-merchant
+
+*** Test Cases ***
+Get_concrete_product_without_offers
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/product-offers
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 0
+
+Get_all_concrete_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /concrete-products/${abstract_product.product_with_concrete_offers.concrete_sku}/product-offers?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][id] ${active_offer_2}
+ And Response body parameter should be: [data][0][type] product-offers
+ And Response body parameter should be in: [data][0][attributes][isDefault] True False
+ And Response body parameter should be: [data][0][attributes][merchantReference] ${merchant_sony_experts_id}
+ And Response body parameter should not be EMPTY: [data][0][links][self]
+ And Response body parameter should contain: [data][0][attributes] merchantSku
+ And Response should contain the array of a certain size: [included] 6
+ And Response should contain the array of a certain size: [data][0][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+ And Response body has correct self link
+
+Get_all_product_offer_info_with_product_offer_prices_and_product_offer_availabilities_and_merchants_included
+ When I send a GET request: /product-offers/${offer_with_merchant_sku}?include=product-offer-prices,product-offer-availabilities,merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${offer_with_merchant_sku}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.spryker.merchant_reference}
+ And Response body parameter should not be EMPTY: [data][links][self]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantSku]
+ And Response should contain the array of a certain size: [included] 3
+ And Response should contain the array of a certain size: [data][relationships] 3
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include should contain certain entity type: product-offer-availabilities
+ And Response include should contain certain entity type: merchants
+ And Response include element has self link: product-offer-prices
+ And Response include element has self link: product-offer-availabilities
+ And Response include element has self link: merchants
+
+Get_product_offer_with_gross_eur
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 0
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_net_eur
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices&priceMode=${mode.net}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.eur.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.eur.symbol}
+
+Get_product_offer_with_gross_chf
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][netAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][grossAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Get_product_offer_with_net_chf
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices&priceMode=${mode.net}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be in: [data][attributes][isDefault] True False
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: product-offer-prices
+ And Response include element has self link: product-offer-prices
+ And Response body parameter should be: [included][0][attributes][prices][0][grossAmount] None
+ And Response body parameter should be greater than: [included][0][attributes][prices][0][netAmount] 1
+ And Response should contain the array of a certain size: [included][0][attributes][prices][0][currency] 3
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][name] ${currency.chf.name}
+ And Response body parameter should be: [included][0][attributes][prices][0][currency][symbol] ${currency.chf.symbol}
+
+Retrieving_product_offer
+ When I send a GET request: /product-offers/${active_offer}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] False
+ And Response body has correct self link internal
+
+Retrieving_product_offer_including_product_offer_prices
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-prices
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] False
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][product-offer-prices][data]
+ And Response include element has self link: product-offer-prices
+ And Each array element of array in response should contain nested property with value: [included] [attributes][price] ${active_offer_price}
+ And Each array element of array in response should contain nested property with value: [included] id ${active_offer}
+ And Each array element of array in response should contain nested property: [included] type product-offer-prices
+ And Response should contain the array larger than a certain size: [included] 0
+
+Retrieving_product_offer_including_product_offer_availabilities
+ When I send a GET request: /product-offers/${active_offer}?include=product-offer-availabilities
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] False
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][product-offer-availabilities][data]
+ And Response include element has self link: product-offer-availabilities
+ And Each array element of array in response should contain nested property with value: [included] id ${active_offer}
+ And Each array element of array in response should contain nested property: [included] type product-offer-availabilities
+ And Each array element of array in response should contain property with value NOT in: [included] attributes None
+
+Retrieving_product_offer_including_merchants
+ When I send a GET request: /product-offers/${active_offer}?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${active_offer}
+ And Response body parameter should be: [data][type] product-offers
+ And Response body parameter should be: [data][attributes][merchantSku] None
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchant_video_king_id}
+ And Response body parameter should be: [data][attributes][isDefault] False
+ And Response body has correct self link internal
+ And Response body parameter should not be EMPTY: [data][relationships][merchants][data]
+ And Response include element has self link: merchants
+ And Each array element of array in response should contain nested property: [included] type merchants
+ And Each array element of array in response should contain property with value NOT in: [included] type None
+ And Each array element of array in response should contain property with value NOT in: [included] attributes None
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/negative.robot b/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/negative.robot
new file mode 100644
index 0000000..afce372
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/negative.robot
@@ -0,0 +1,293 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue quotation-process spryker-core cart acl customer-account-management customer-access approval-process
+
+*** Test Cases ***
+#POST#
+Create_quote_request_without_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I set Headers: Authorization=
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Create_quote_request_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I set Headers: Authorization=345A9
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Create_quote_request_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ When I send a POST request: /quote-requests {"data":{"type":"Invalid","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ When I send a POST request: /quote-requests {"data":{"type":"","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_with_invalid_cartId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"Test123","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+
+Create_quote_request_with_empty_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: cartUuid => This value should not be blank.
+
+Create_quote_request_from_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 404
+ And Response should return error code: 101
+ And Response reason should be: Not Found
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+
+Create_quote_request_for_cart_with_read_only_access
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Get company user id by customer reference: ${yves_fifth_user.reference}
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":2}}}
+ ... AND Save value to a variable: [data][id] shared_cart_id
+ ... AND I send a PATCH request: /shared-carts/${shared_cart_id} {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":1}}}
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts/${shared_cart_id}?include=cart-permission-groups
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Request for quote denied. User does not have permissions to request quote.
+ And Response should return error code: 4506
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+# #GET#
+Retrieve_quote_requests_with_incorrect_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /quoterequests
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Not Found
+
+Retrieve_quote_requests_without_token
+ When I send a GET request: /quote-requests
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Retrieve_quote_requests_with_invalid_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=324H4
+ When I send a GET request: /quote-requests
+ Then Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Retrieve_quote_request_with_incorrect_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /quote-requests/test123
+ Then Response status code should be: 404
+ And Response should return error code: 4501
+ And Response reason should be: Not Found
+ And Response should return error message: Quote request not found.
+
+Retrieve_quote_request_by_id_with_incorrect_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /quoterequests/test123
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: Not Found
+
+#PATCH#
+Update_quote_request_without_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ ... AND I set Headers: Authorization=
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_empty_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a PATCH request: /quote-requests/ {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_incorrect_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ When I send a PATCH request: /quote-requests/test123 {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 4501
+ And Response should return error message: Quote request not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_empty_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"quote-requests","attributes":{"cartUuid":"","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: cartUuid => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_invalid_cart_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"quote-requests","attributes":{"cartUuid":"Invalid","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 101
+ And Response should return error message: Cart with given uuid not found.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_invalid_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"invalid","attributes":{"cartUuid":"Invalid","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_empty_type
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"","attributes":{"cartUuid":"Invalid","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Update_quote_request_with_another_user_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Save value to a variable: [data][attributes][accessToken] first_user_token
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 404
+ And Response should return error code: 4501
+ And Response reason should be: Not Found
+ And Response should return error message: Quote request not found.
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${first_user_token}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
diff --git a/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/positive.robot b/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/positive.robot
new file mode 100644
index 0000000..6056a44
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/quote_requests_endpoint/quote_requests/positive.robot
@@ -0,0 +1,522 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue quotation-process spryker-core cart acl customer-account-management customer-access approval-process
+
+*** Test Cases ***
+#POST#
+Create_quote_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}","quantity": 1}}}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] quote_request_id
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0][groupKey] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][1][groupKey] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] productOfferReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] merchantReference
+ And Response body parameter should be: [data][attributes][shownVersion][cart][items][0][sku] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][items][1][sku] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}
+ And Each array element of array in response should contain nested property with value: [data][attributes][shownVersion][cart][items] quantity 1
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] quantity
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] abstractSku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] amount
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundle
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundleItem
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] salesUnit
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] calculations
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response body has correct self link for created entity: ${quote_request_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_with_included_customers_&_comapny_users_&_company_business_units_and_concrete_products
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}","quantity": 1}}}
+ When I send a POST request: /quote-requests?include=customers,company-users,company-business-units,concrete-products {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] groupKey
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] productOfferReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] merchantReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] sku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] quantity
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] abstractSku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] amount
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundle
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundleItem
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] salesUnit
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] calculations
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response should contain the array of a certain size: [data][relationships] 4
+ And Response should contain the array of a certain size: [data][relationships][company-users][data] 1
+ And Response should contain the array of a certain size: [data][relationships][company-business-units][data] 1
+ And Response should contain the array of a certain size: [data][relationships][customers][data] 1
+ And Response should contain the array larger than a certain size: [data][relationships][concrete-products][data] 1
+ And Each Array Element Of Array In Response Should Contain Property: [included] type
+ And Each Array Element Of Array In Response Should Contain Property: [included] id
+ And Each Array Element Of Array In Response Should Contain Property: [included] attributes
+ And Each Array Element Of Array In Response Should Contain Property: [included] links
+ And Response include should contain certain entity type: company-business-units
+ And Response include should contain certain entity type: customers
+ And Response include should contain certain entity type: company-users
+ And Response include should contain certain entity type: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_without_delivery_date_and_note
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}","quantity": 1}}}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}"}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] quote_request_id
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0][groupKey] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][1][groupKey] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] productOfferReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] merchantReference
+ And Response body parameter should be: [data][attributes][shownVersion][cart][items][0][sku] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][items][1][sku] ${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}
+ And Each array element of array in response should contain nested property with value: [data][attributes][shownVersion][cart][items] quantity 1
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] quantity
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] abstractSku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] amount
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundle
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundleItem
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] salesUnit
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] calculations
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response body has correct self link for created entity: ${quote_request_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_with_empty_meta_data
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ And Save value to a variable: [data][id] cart_id
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ And I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_2}","quantity": 1}}}
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"","delivery_date":"","note":""}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] quote_request_id
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals] discountTotal
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] groupKey
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] productOfferReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] merchantReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] sku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] quantity
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] abstractSku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] amount
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundle
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundleItem
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] salesUnit
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] calculations
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response body has correct self link for created entity: ${quote_request_id}
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Create_quote_request_for_cart_with_full_access_permissions
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND Save value to a variable: [data][attributes][accessToken] userToken
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${cartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND I send a GET request: /company-users
+ ... AND Get company user id by customer reference: ${yves_fifth_user.reference}
+ ## Giving_full_cart_access_to_the_User_by_using_quote_request.cart_permission_id ##
+ ... AND I send a POST request: /carts/${cartId}/shared-carts {"data":{"type":"shared-carts","attributes":{"idCompanyUser":"${companyUserId}","idCartPermissionGroup":${quote_request.cart_permission_id}}}}
+ ... AND Save value to a variable: [data][id] shared_cart_id
+ ... AND I get access token for the customer: ${yves_fifth_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a GET request: /carts/${shared_cart_id}?include=cart-permission-groups
+ When I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Save value to a variable: [data][id] quote_request_id
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][discountTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] groupKey
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] productOfferReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] merchantReference
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] sku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] quantity
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] abstractSku
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] amount
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundle
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] configuredBundleItem
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] salesUnit
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] calculations
+ And Each array element of array in response should contain property: [data][attributes][shownVersion][cart][items] selectedProductOptions
+ And Response body has correct self link for created entity: ${quote_request_id}
+ [Teardown] Run Keywords I set Headers: Authorization=Bearer ${userToken}
+ ... AND I send a DELETE request: /carts/${cartId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+# #GET#
+Retrieves_quote_request_list_when_no_RFQ
+ [Setup] Run Keywords I get access token for the customer: ${yves_sixth_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /quote-requests
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Retrieves_quote_request_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ When I send a GET request: /quote-requests
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] [type] quote-requests
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] quoteRequestReference
+ And Each array element of array in response should contain nested property: [data] [attributes] status
+ And Each array element of array in response should contain nested property: [data] [attributes] quoteRequestReference
+ And Each array element of array in response should contain nested property: [data] [attributes] isLatestVersionVisible
+ And Each array element of array in response should contain nested property: [data] [attributes] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes] validUntil
+ And Each array element of array in response should contain nested property: [data] [attributes] versions
+ And Each array element of array in response should contain nested property: [data] [attributes] shownVersion
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion] version
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion] versionReference
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion] createdAt
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion] metadata
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion] cart
+ And Each array element of array in response should contain nested property with value: [data] [attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][shownVersion][cart][store] ${store.de}
+ And Each array element of array in response should contain nested property with value: [data] [attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][totals] expenseTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][totals] discountTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][totals] taxTotal
+ And Each array element of array in response should be greater than: [data] [attributes][shownVersion][cart][totals][subtotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][shownVersion][cart][totals][grandTotal] 0
+ And Each array element of array in response should be greater than: [data] [attributes][shownVersion][cart][totals][priceToPay] 0
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart] billingAddress
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart] items
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] groupKey
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] productOfferReference
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] sku
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] quantity
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] abstractSku
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] amount
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] configuredBundle
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] configuredBundleItem
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] salesUnit
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] calculations
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart][items][0] selectedProductOptions
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart] discounts
+ And Each array element of array in response should contain nested property: [data] [attributes][shownVersion][cart] shipments
+ And Each array element of array in response should contain property: [data] links
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Retrieves_quote_request_by_requestId
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a GET request: /quote-requests/${quoteRequestId}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][discountTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] groupKey
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] productOfferReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] merchantReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] sku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] quantity
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] abstractSku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] amount
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundle
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundleItem
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] salesUnit
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] calculations
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+Retrieve_quote_request_version
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ ... AND Save value to a variable: [data][attributes][shownVersion][versionReference] quote_request_version
+ When I send a GET request: /quote-requests/${quoteRequestId}?quoteRequestVersionReference=${quote_request_version}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][discountTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] groupKey
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] productOfferReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] merchantReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] sku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] quantity
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] abstractSku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] amount
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundle
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundleItem
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] salesUnit
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] calculations
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
+
+
+#PATCH#
+Update_quote_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items {"data": {"type": "items","attributes": {"sku": "${concrete.available_product.with_stock_and_never_out_of_stock.sku_1}","quantity": 1}}}
+ ... AND I send a POST request: /quote-requests {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"purchase_order_number":"${quote_request.purchase_order_number}","delivery_date":"${quote_request.delivery_date}","note":"${quote_request.note}"}}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] quoteRequestId
+ When I send a PATCH request: /quote-requests/${quoteRequestId} {"data":{"type":"quote-requests","attributes":{"cartUuid":"${cart_id}","meta":{"note":"Test1"}}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] quote-requests
+ And Response body parameter should not be EMPTY: [data][id]
+ And Response body parameter should contain: [data][attributes] quoteRequestReference
+ And Response body parameter should contain: [data][attributes] status
+ And Response body parameter should contain: [data][attributes] isLatestVersionVisible
+ And Response body parameter should contain: [data][attributes] createdAt
+ And Response body parameter should contain: [data][attributes] validUntil
+ And Response body parameter should not be EMPTY: [data][attributes][versions][0]
+ And Response body parameter should contain: [data][attributes][shownVersion] version
+ And Response body parameter should contain: [data][attributes][shownVersion] versionReference
+ And Response body parameter should contain: [data][attributes][shownVersion] createdAt
+ And Response body parameter should be: [data][attributes][shownVersion][cart][priceMode] ${mode.gross}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][store] ${store.de}
+ And Response body parameter should be: [data][attributes][shownVersion][cart][currency] ${currency.eur.code}
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][expenseTotal]
+ And Response body parameter should not be EMPTY: [data][attributes][shownVersion][cart][totals][discountTotal]
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][totals][taxTotal] tax_rate
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][taxTotal][amount] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][subtotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][grandTotal] 1
+ And Response body parameter should be greater than: [data][attributes][shownVersion][cart][totals][priceToPay] 1
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] billingAddress
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] groupKey
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] productOfferReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] merchantReference
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] sku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] quantity
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] abstractSku
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] amount
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundle
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] configuredBundleItem
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] salesUnit
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] calculations
+ And Response body parameter should contain: [data][attributes][shownVersion][cart][items][0] selectedProductOptions
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] discounts
+ And Response body parameter should contain: [data][attributes][shownVersion][cart] shipments
+ [Teardown] Run Keywords I send a DELETE request: /carts/${cart_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/return_endpoints/return_reasons/positive.robot b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/return_reasons/positive.robot
new file mode 100644
index 0000000..df24272
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/return_reasons/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue return-management marketplace-return-management
+
+*** Test Cases ***
+#GET requests
+Get_return_reason
+ When I send a GET request: /return-reasons
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type return-reasons
+ And Each array element of array in response should contain nested property: [data] [attributes] reason
+ And Response should contain the array of a certain size: [data] ${return_reasons_qty}
+ And Each array element of array in response should contain nested property with value: [data] [id] None
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/negative.robot b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/negative.robot
new file mode 100644
index 0000000..d838921
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/negative.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+ #POST#
+Create_a_return_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Create_a_return_with_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Create_return_for_order_item_that_cannot_be_returned
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_not_returnable
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_not_returnable}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${Uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_a_return_with_order_is_not_returnable_for_merchant
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${merchants.sony_experts.concrete_product_with_offer_sku}","quantity": 10, "merchantReference" : "${merchants.sony_experts.merchant_reference}", "productOfferReference" : "${merchants.sony_experts.merchant_offer_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_not_returnable_merchant
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_not_returnable_merchant}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] returnableSalesOrderItemUuid
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${returnableSalesOrderItemUuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_with_invalid_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${random}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_uuid
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+Create_return_without_returnItems_reason
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"920fc22f-3fb6-53ec-bc5e-c4d321115462","reason":""}]}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: "Return cant be created."
+ And Response should return error code: 3601
+
+
+#GET#
+Get_lists_of_returns_with_Invalid_access_token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a GET request: /returns
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ And Response should return error code: 001
+
+Get_lists_of_returns_without_access_token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /returns
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+ And Response should return error code: 002
+
+Get_return_by_Id_with_Invalid_return_reference
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /returns/${random}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error message: "Cant find return by the given return reference."
+ And Response should return error code: 3602
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/positive.robot b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/positive.robot
new file mode 100644
index 0000000..7bfae25
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/return_endpoints/returns/positive.robot
@@ -0,0 +1,355 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Tags glue marketplace-return-management return-management checkout cart spryker-core refunds
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+
+*** Test Cases ***
+### Important CHECKOUT and CHECKOUT-DATA endpoints require Item ID and NOT intem sku. To get item id and include to the cart endpoint.
+### Example:
+###I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${concrete_product.random_weight.sku}","quantity": 1,"salesUnit": {"id": "${sales_unit_id}","amount": 5}}}}
+### Save value to a variable: [included][0][id] test
+### I send a POST request: /checkout {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name_1}","paymentMethodName": "${payment.method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${test}"]}}}
+
+#POST#
+Create_a_return
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND Cleanup all customer carts
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ### steps below just duplicate the order creation and status change. This is needed as we 'hack' the order status in the database. ###
+ ### Needs to be done only once in the first test ###
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Save value to a variable: [data][id] returnId
+ And Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link for created entity: ${returnId}
+
+Create_a_return_include_return_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ When I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data] id
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should not be empty: [included][0][attributes][uuid]
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response body parameter should contain: [included][0][attributes] orderItemUuid
+
+
+#GET#
+Get_lists_of_returns
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return_list
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return_list}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+
+
+Get_lists_of_returns_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${product_with_alternative.concrete_sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_in_return_list_items
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_in_return_list_items}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Each array element of array in response should contain property: [data] relationships
+ And Each array element of array in response should contain nested property: [data] [relationships] return-items
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] type
+ And Each array element of array in response should contain nested property: [data] [relationships][return-items][data][0] id
+ And Each array element of array in response should contain nested property with value: [data] [relationships][return-items][data][0][type] return-items
+ And Response include element has self link: return-items
+ And Response include should contain certain entity type: return-items
+ And Response body has correct self link
+
+#GET#
+Get_return_by_Id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnReference}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body has correct self link internal
+
+Get_return_by_Id_include_return-items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data":{"type":"carts","attributes":{"priceMode":"${mode.gross}","currency":"${currency.eur.code}","store":"${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cartId
+ ... AND I send a POST request: /carts/${CartId}/items?include=items {"data":{"type":"items","attributes":{"sku":"${concrete.available_product.with_stock_and_never_out_of_stock.sku}","quantity":"1"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${CartId}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "DummyPayment","paymentMethodName": "Credit Card"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] productPrice
+ ... AND Update order status in Database: shipped ${uuid}
+ ... AND I send a POST request: /returns?include=return-items {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][attributes][returnReference] returnReference
+ ... AND Save value to a variable: [included][0][attributes][orderItemUuid] orderItemUuid
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnReference}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnReference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnReference}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${productPrice}
+ And Response body parameter should contain: [data] relationships
+ And Response body parameter should be: [data][relationships][return-items][data][0][type] return-items
+ And Response body parameter should contain: [data][relationships][return-items][data][0] id
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][type] return-items
+ And Response body parameter should contain: [included][0] id
+ And Response body parameter should be: [included][0][attributes][reason] ${return_reason_damaged}
+ And Response body parameter should be: [included][0][attributes][orderItemUuid] ${orderItemUuid}
+
+Retrieves_list_of_returns_included_merchants
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "${merchants.sony_experts.concrete_product_with_offer_sku}","quantity": 4, "merchantReference" : "${merchants.sony_experts.merchant_reference}", "productOfferReference" : "${merchants.sony_experts.merchant_offer_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item_merch
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item_merch}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [data][attributes][orderReference] order_reference
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND I send a POST request: /returns?include=merchants {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ When I send a GET request: /returns?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property with value: [data] type returns
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property: [data] links
+ And Each array element of array in response should contain nested property: [data] [attributes] merchantReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnReference
+ And Each array element of array in response should contain nested property: [data] [attributes] store
+ And Each array element of array in response should contain nested property: [data] [attributes] customerReference
+ And Each array element of array in response should contain nested property: [data] [attributes] returnTotals
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] refundTotal
+ And Each array element of array in response should contain nested property: [data] [attributes][returnTotals] remunerationTotal
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Array element should contain nested array at least once: [data] [relationships]
+ And Response body parameter should be: [data][0][relationships][merchants][data][0][type] merchants
+ And Response body parameter should be: [data][0][relationships][merchants][data][0][id] MER000006
+ And Response include element has self link: merchants
+ And Response include should contain certain entity type: merchants
+ And Response body has correct self link
+
+Retrieves_return_by_id_with_returns_items_included
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${merchants.sony_experts.concrete_product_with_offer_sku}","quantity": 4, "merchantReference" : "${merchants.sony_experts.merchant_reference}", "productOfferReference" : "${merchants.sony_experts.merchant_offer_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item_included
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item_included}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.sony_experts.merchant_reference}
+ ${return_result}= Run Keyword And Ignore Error I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Run Keyword If "${return_result[0]}" != "PASS" Run Keywords Log Retry sending return request AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.sony_experts.merchant_reference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][return-items]
+ And Each array element of array in response should contain property: [data][relationships][return-items][data] type
+ And Each array element of array in response should contain property: [data][relationships][return-items][data] id
+ And Response body parameter should not be EMPTY: [included]
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Each array element of array in response should contain nested property: [included] [attributes] uuid
+ And Each array element of array in response should contain property with value: [included] type return-items
+ And Each array element of array in response should contain property with value in: [included] [attributes][orderItemUuid] ${uuid} ${uuid}
+ And Each array element of array in response should contain property with value in: [included] [attributes][reason] ${return_reason_damaged} ${return_reason_damaged}
+ And Response body has correct self link internal
+
+Retrieves_return_by_id_for_sales_order
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${merchants.sony_experts.concrete_product_with_offer_sku}","quantity": 4, "merchantReference" : "${merchants.sony_experts.merchant_reference}", "productOfferReference" : "${merchants.sony_experts.merchant_offer_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item_sales
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item_sales}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.sony_experts.merchant_reference}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=return-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should contain: [data][attributes] merchantReference
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+
+Retrieves_return_by_id_with_merchants_included
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /carts {"data": {"type": "carts","attributes": {"priceMode": "${mode.gross}","currency": "${currency.eur.code}","store": "${store.de}","name": "${test_cart_name}-${random}"}}}
+ ... AND Save value to a variable: [data][id] cart_id
+ ... AND I send a POST request: /carts/${cartId}/items?include=items {"data": {"type": "items","attributes": {"sku": "${merchants.sony_experts.concrete_product_with_offer_sku}","quantity": 4, "merchantReference" : "${merchants.sony_experts.merchant_reference}", "productOfferReference" : "${merchants.sony_experts.merchant_offer_id}"}}}
+ ... AND Save value to a variable: [included][0][id] item_id_id_item_included_m
+ ... AND I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user.email}","salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user.salutation}","firstName": "${yves_user.first_name}","lastName": "${yves_user.last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment.provider_name}","paymentMethodName": "${payment.method_name}","paymentSelection": "${payment.selection_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["${item_id_id_item_included_m}"]}}}
+ ... AND Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ ... AND Save value to a variable: [included][0][attributes][items][0][refundableAmount] refundable_amount
+ ... AND Update order status in Database: shipped by merchant ${uuid}
+ ... AND Create merchant order for the item in DB and change status: shipped ${uuid} ${merchants.sony_experts.merchant_reference}
+ ... AND I send a POST request: /returns {"data":{"type":"returns","attributes":{"store":"${store.de}","returnItems":[{"salesOrderItemUuid":"${uuid}","reason":"${return_reason_damaged}"}]}}}
+ ... AND Save value to a variable: [data][id] returnId
+ When I send a GET request: /returns/${returnId}?include=merchants
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] returns
+ And Response body parameter should be: [data][id] ${returnId}
+ And Response body parameter should be: [data][attributes][merchantReference] ${merchants.sony_experts.merchant_reference}
+ And Response body parameter should be: [data][attributes][returnReference] ${returnId}
+ And Response body parameter should be: [data][attributes][store] ${store.de}
+ And Response body parameter should be: [data][attributes][customerReference] ${yves_user.reference}
+ And Response body parameter should be: [data][attributes][returnTotals][refundTotal] 0
+ And Response body parameter should be: [data][attributes][returnTotals][remunerationTotal] ${refundable_amount}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][merchants]
+ And Response should contain the array larger than a certain size: [included] 0
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response include element has self link: merchants
+ And Response include should contain certain entity type: merchants
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/negative.robot b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/negative.robot
new file mode 100644
index 0000000..72a7e83
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/negative.robot
@@ -0,0 +1,12 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue search catalog
+
+
+
+*** Test Cases ***
+Search_without_query_parameter
+ When I send a GET request: /catalog-search?
+ Then Response status code should be: 200
diff --git a/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/positive.robot b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/positive.robot
new file mode 100644
index 0000000..a3c817f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search/positive.robot
@@ -0,0 +1,636 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue search catalog product
+
+
+*** Test Cases ***
+Search_with_empty_search_criteria_all_default_values_check
+ When I send a GET request: /catalog-search?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][spellingSuggestion] None
+ #Sorting
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamNames] ${default_qty.sorting_options}
+ And Response should contain the array of a certain size: [data][0][attributes][sort][sortParamLocalizedNames] ${default_qty.sorting_options}
+ And Response body parameter should contain: [data][0][attributes] currentSortParam
+ And Response body parameter should contain: [data][0][attributes] currentSortOrder
+ #Pagination
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][currentItemsPerPage] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][pagination][config][validItemsPerPageOptions] 3
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.middle}
+ And Response body parameter should contain: [data][0][attributes][pagination][config][validItemsPerPageOptions] ${ipp.biggest}
+ #Abstract products
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] prices
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] abstractSku
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.eur.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.eur.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.eur.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ #Filters - category
+ And Response body parameter should contain: [data][0][attributes] valueFacets
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][name] category
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][localizedName] Categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] ${default_qty.categories}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][config][isMultiValued] False
+ #Filters - labels
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][name] label
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][localizedName] Product Labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] ${default_qty.labels}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][config][isMultiValued] True
+ #Filters - product class
+ And Response body parameter should be in: [data][0][attributes][valueFacets][2][name] Product Class product-class
+ And Response body parameter should be in: [data][0][attributes][valueFacets][2][localizedName] Product Class Product Classes
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][2][values] ${default_qty.product_classes}
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][2][config][isMultiValued] True
+ #Filters - color
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][name] color
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][localizedName] Color
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][3][values] ${default_qty.colors}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][config][isMultiValued] True
+ #Filters - material
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][name] storage_capacity
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][localizedName] Storage Capacity
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] ${default_qty.material}
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][4][config][isMultiValued] True
+ #Filters - brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][name] brand
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][localizedName] Brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] ${default_qty.brands}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][config][isMultiValued] False
+ #Filters - rating
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][name] price-DEFAULT-EUR-GROSS_MODE
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][localizedName] Price range
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][min] ${default_price_range.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][max] ${default_price_range.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_price_range.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_price_range.max}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][config][isMultiValued] False
+ #Filters - category tree
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] nodeId
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] name
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] docCount
+ And Each array element of array in response should contain value: [data][0][attributes][categoryTreeFilter] children
+ #Selflinks
+ And Response body has correct self link
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_by_attribute_that_does_not_return_products
+ When I send a GET request: /catalog-search?q=fake
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 0
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][4][values] 0
+ And Response body has correct self link
+
+Search_by_concrete_sku
+ When I send a GET request: /catalog-search?q=${concrete_product_with_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 1
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_abstract_sku
+ When I send a GET request: /catalog-search?q=${concrete_product_with_alternative.abstract_sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][1][values] 1
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_full_name
+ When I send a GET request: /catalog-search?q=${concrete_product_with_alternative.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_name_substring
+ When I send a GET request: /catalog-search?q=ACER
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should NOT be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ #categories
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][0][values] 4
+ #labels
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][1][values] 0
+ #brand
+ And Response should contain the array larger than a certain size: [data][0][attributes][valueFacets][5][values] 1
+ And Response body has correct self link
+
+Search_by_attribute_(brand)
+ When I send a GET request: /catalog-search?q=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 21
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should contain: [data][0][attributes][abstractProducts][0][abstractName] ${brand_1}
+ #brand
+ And Response should contain the array of a certain size: [data][0][attributes][valueFacets][5][values] 2
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] None
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][values][0][value] ${brand_1}
+ And Response body has correct self link
+
+Search_by_several_attributes
+ When I send a GET request: /catalog-search?q=${color_3}+${material_3}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 2
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 2
+
+# FILTERING #
+
+Filter_by_rating_only_min
+ When I send a GET request: /catalog-search?q=&rating[min]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 6
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default_3}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_active.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_active.max}
+ And Response body parameter should not be EMPTY: [data][0][attributes][rangeFacets][0][activeMin]
+ And Response body parameter should not be EMPTY: [data][0][attributes][rangeFacets][0][activeMax]
+
+
+Filter_by_rating_only_max
+ When I send a GET request: /catalog-search?q=&rating[max]=${default_price_range.max}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 6
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default_3}
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMin] ${default_active.min}
+ And Response body parameter should be: [data][0][attributes][rangeFacets][0][activeMax] ${default_active.max}
+ And Response body parameter should not be EMPTY: [data][0][attributes][rangeFacets][0][activeMin]
+ And Response body parameter should not be EMPTY: [data][0][attributes][rangeFacets][0][activeMax]
+
+
+Filter_by_rating_Min_max
+ When I send a GET request: /catalog-search?q=&rating[min]=3&rating[max]=3
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ #rating facets
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMin] 3
+ And Response body parameter should be: [data][0][attributes][rangeFacets][1][activeMax] 3
+
+Filter_by_brand_one_brand
+ When I send a GET request: /catalog-search?q=&brand=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 19
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] ${brand_1}
+ And Response body has correct self link
+
+Filter_by_brand_two_brands
+ When I send a GET request: /catalog-search?q=&brand[]=${brand_2}&brand[]=${brand_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 19
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue][0] ${brand_2}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue][1] ${brand_1}
+
+Filter_by_brand_empty_brand
+ When I send a GET request: /catalog-search?q=&brand=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] ${EMPTY}
+ And Response body has correct self link
+
+Filter_by_brand_non_existing_brand
+ When I send a GET request: /catalog-search?q=&brand=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][5][activeValue] test123
+ And Response body has correct self link
+
+Filter_by_label_one_label
+ When I send a GET request: /catalog-search?q=&label=${label.new}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 5
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 5
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue] ${label.new}
+ And Response body has correct self link
+
+Filter_by_label_two_labels
+ When I send a GET request: /catalog-search?q=&label[]=${label.new}&label[]=${label.sale}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 65
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${label.new}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][1] ${label.sale}
+
+Filter_by_label_non_existing_label
+ When I send a GET request: /catalog-search?q=&label[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] test123
+
+Filter_by_label_empty_label
+ When I send a GET request: /catalog-search?q=&label[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][1][activeValue][0] ${EMPTY}
+
+Filter_by_color_one_color
+ When I send a GET request: /catalog-search?q=&color=${color_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 10
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue] ${color_2}
+ #additional checks that other filers react accordingly and reduce the number of available facets to match facets present for the found products
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][0] ${default_qty.categories}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][3] ${default_qty.materials}
+ And Response should contain the array smaller than a certain size: [data][0][attributes][valueFacets][5] ${default_qty.brands}
+ And Response body has correct self link
+
+Filter_by_color_two_colors
+ When I send a GET request: /catalog-search?q=&color[]=${color_1}&color[]=${color_2}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 10
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] ${color_1}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][1] ${color_2}
+
+Filter_by_color_non_existing_color
+ When I send a GET request: /catalog-search?q=&color[]=test123
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] 0
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 0
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] test123
+
+Filter_by_color_empty_color
+ When I send a GET request: /catalog-search?q=&color[]=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][3][activeValue][0] ${EMPTY}
+
+Filter_by_valid_main_category
+ When I send a GET request: /catalog-search?q=&category=${category_lvl1.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl1.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl1.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Array element should contain property with value at least once: [data][0][attributes][categoryTreeFilter] docCount ${${category_lvl1.qty}}
+ And Array element should contain nested array with property and value at least once: [data][0][attributes][categoryTreeFilter] [children] docCount ${category_lvl2.qty}
+ And Response body has correct self link
+
+Filter_by_valid_subcategory
+ When I send a GET request: /catalog-search?q=&category=${category_lvl2.id}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][pagination][numFound] ${category_lvl2.qty}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][valueFacets][0][activeValue] ${category_lvl2.id}
+ # check that category tree is correctly updated
+ And Response should contain the array of a certain size: [data][0][attributes][categoryTreeFilter] ${category_tree_branches_qty}
+ And Response body parameter should be: [data][0][attributes][categoryTreeFilter][0][docCount] 0
+ And Array element should contain property with value at least once: [data][0][attributes][categoryTreeFilter] docCount ${${category_lvl2.qty}}
+ And Array element should contain nested array with property and value at least once: [data][0][attributes][categoryTreeFilter] [children] docCount ${category_lvl2.qty}
+ And Response body parameter should be less than: [data][0][attributes][categoryTreeFilter][3][children][0][children][0][docCount] ${category_lvl2.qty}
+ And Response body has correct self link
+
+Search_with_specific_currency
+ When I send a GET request: /catalog-search?q=¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] 1
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be greater than: [data][0][attributes][pagination][maxPage] 1
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][code] ${currency.chf.code}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][symbol] ${currency.chf.symbol}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][prices][0][currency][name] ${currency.chf.name}
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 1
+ And Response body has correct self link
+
+# PAGINATION AND SORTING #
+
+Search_set_specific_page_with_default_ipp
+ # here page 4 is selected using offset because 36/12=3 full pages, search shows the next page after the offset
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.default}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 4
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+
+Search_set_specific_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.middle}&page[offset]=36
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 2
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 10
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.middle}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_set_last_page_and_nondefault_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=${ipp.biggest}&page[offset]=${total_number_of_products_in_search}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 7
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] 7
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 0
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][prev]
+
+Search_set_invalid_ipp
+ When I send a GET request: /catalog-search?q=&page[limit]=18&page[offset]=1
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be greater than: [data][0][attributes][pagination][numFound] ${min_number_of_products_in_search}
+ And Response body parameter should be less than: [data][0][attributes][pagination][numFound] ${max_number_of_products_in_search}
+ And Response body parameter should be: [data][0][attributes][pagination][currentPage] 1
+ And Response body parameter should be: [data][0][attributes][pagination][maxPage] ${default_qty.ipp_pages}
+ And Response body parameter should be: [data][0][attributes][pagination][config][defaultItemsPerPage] ${ipp.default}
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] ${ipp.default}
+ And Response body parameter should not be EMPTY: [links][self]
+ And Response body parameter should not be EMPTY: [links][last]
+ And Response body parameter should not be EMPTY: [links][first]
+ And Response body parameter should not be EMPTY: [links][next]
+
+Search_sort_by_name_asc
+ When I send a GET request: /catalog-search?q=&sort=name_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] A
+ And Response body has correct self link
+
+Search_sort_by_name_desc
+ When I send a GET request: /catalog-search?q=&sort=name_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] name_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should start with: [data][0][attributes][abstractProducts][0][abstractName] V
+ And Response body has correct self link
+
+Search_sort_by_rating
+ When I send a GET request: /catalog-search?q=&sort=rating
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] rating
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_sku_highest_rating}
+ And Response body has correct self link
+
+
+Search_sort_by_price_asc
+ When I send a GET request: /catalog-search?q=&sort=price_asc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_asc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] asc
+ And Array element should contain property with value less than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 170
+ And Response body has correct self link
+
+Search_sort_by_price_desc
+ When I send a GET request: /catalog-search?q=&sort=price_desc
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response body parameter should be: [data][0][attributes][sort][currentSortParam] price_desc
+ And Response body parameter should be: [data][0][attributes][sort][currentSortOrder] desc
+ And Array element should contain property with value greater than at least once: [data][0][attributes][abstractProducts][0][prices] DEFAULT 10000
+ And Response body has correct self link
+
+Search_by_abstract_sku_with_abstract_include
+ When I send a GET request: /catalog-search?q=${concrete_product_with_alternative.abstract_sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][0][type] catalog-search
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 1
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${concrete_product_with_alternative.abstract_sku}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_alternative.name}
+ And Response should contain the array of a certain size: [data][0][relationships][abstract-products][data] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response include should contain certain entity type: abstract-products
+ And Response include element has self link: abstract-products
+ And Response body parameter should be: [included][0][id] ${concrete_product_with_alternative.abstract_sku}
+ And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search_suggestions/positive.robot b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search_suggestions/positive.robot
new file mode 100644
index 0000000..1b83075
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/search_endpoints/catalog_search_suggestions/positive.robot
@@ -0,0 +1,259 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue search catalog product discontinued-products
+
+*** Test Cases ***
+Get_search_suggestions_without_query_parameter
+ When I send a GET request: /catalog-search-suggestions
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_empty_q_parameter
+ When I send a GET request: /catalog-search-suggestions?q=
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_non_existing_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=000000
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_discontinued_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_all_attributes_data
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.name_lower_case}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.name_lower_case}
+ And Each array element of array in response should contain property: [data][0][attributes][categories] name
+ And Each array element of array in response should contain property: [data][0][attributes][categories] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPages] url
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][abstractSku] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] price
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractName
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] abstractSku
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] url
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts] images
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][categoryCollection] url
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] name
+ And Each array element of array in response should contain property: [data][0][attributes][cmsPageCollection] url
+ And Response body has correct self link
+
+Get_search_suggestions_with_few_symbols
+ When I send a GET request: /catalog-search-suggestions?q=le
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Each array element of array in response should contain value: [data][0][attributes][completion] le
+ And Each array element of array in response should contain value: [data][0][attributes][abstractProducts] le
+ And Response body has correct self link
+
+Get_search_suggestions_with_11_symbols
+ When I send a GET request: /catalog-search-suggestions?q=acer cb5-31
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 1
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 2
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 2
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 1
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 2
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 2
+ And Response body has correct self link
+
+Get_search_suggestions_with_concrete_product_sku
+ When I send a GET request: /catalog-search-suggestions?q=${concrete_product_with_concrete_product_alternative.sku}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${concrete_product_with_concrete_product_alternative.sku}
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${concrete_product_with_concrete_product_alternative.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_product_with_alternative.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][images]
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_pages
+ When I send a GET request: /catalog-search-suggestions?q=${cms_pages.first_cms_page.name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][completion] ${cms_pages.first_cms_page.name_lower_case}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][name] ${cms_pages.first_cms_page.name}
+ And Response body parameter should be: [data][0][attributes][cmsPages][0][url] ${cms_pages.first_cms_page.url_en}
+ And Response body has correct self link
+
+Get_search_suggestions_with_category_collection
+ When I send a GET request: /catalog-search-suggestions?q=${category_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][name] ${category_collection_name}
+ And Response body parameter should be: [data][0][attributes][categoryCollection][0][url] ${category_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_cms_page_collection
+ When I send a GET request: /catalog-search-suggestions?q=${cms_page_collection_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][name] ${cms_page_collection_name}
+ And Response body parameter should be: [data][0][attributes][cmsPageCollection][0][url] ${cms_page_collection_url}
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_color
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}&color=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][categories] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPages] 2
+ And Response should contain the array larger than a certain size: [data][0][attributes][abstractProducts] 0
+ And Response should contain the array of a certain size: [data][0][attributes][categoryCollection] 0
+ And Response should contain the array of a certain size: [data][0][attributes][cmsPageCollection] 2
+ And Response body has correct self link
+
+Get_search_suggestions_with_brand_and_currency
+ When I send a GET request: /catalog-search-suggestions?q=${brand_name}¤cy=${currency.chf.code}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${brand_name}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 10
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body has correct self link
+
+Get_search_suggestions_with_color
+ When I send a GET request: /catalog-search-suggestions?q=${color_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Each array element of array in response should contain value: [data][0][attributes][completion] ${color_5}
+ And Response should contain the array of a certain size: [data][0][attributes][completion] 2
+ And Response should contain the array of a certain size: [data][0][attributes][abstractProducts] 10
+ And Response body has correct self link
+
+Get_search_suggestions_with_abstract_product_sku_and_included_abstract_products
+ When I send a GET request: /catalog-search-suggestions?q=${abstract_available_product_with_stock.sku}&include=abstract-products
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][0][type] catalog-search-suggestions
+ And Response body parameter should be: [data][0][id] None
+ And Response body parameter should be greater than: [data][0][attributes][abstractProducts][0][price] 0
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractName] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [data][0][attributes][abstractProducts][0][abstractSku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should not be EMPTY: [data][0][attributes][abstractProducts][0][url]
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlSmall
+ And Each array element of array in response should contain property: [data][0][attributes][abstractProducts][0][images] externalUrlLarge
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][type] abstract-products
+ And Response body parameter should be: [data][0][relationships][abstract-products][data][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][type] abstract-products
+ And Response body parameter should be: [included][0][id] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${abstract_available_product_with_stock.sku}
+ And Response body parameter should be: [included][0][attributes][averageRating] None
+ And Response body parameter should be: [included][0][attributes][reviewCount] 0
+ And Response body parameter should be: [included][0][attributes][name] ${abstract_available_product_with_stock.name}
+ And Response body parameter should be: [included][0][attributes][description] ${abstract_available_product_with_stock.description}
+ And Response body parameter should be: [included][0][attributes][attributes][internal_memory] ${internal_memory}
+ And Response body parameter should be: [included][0][attributes][attributes][aspect_ratio] ${aspect_ratio}
+ And Response body parameter should be: [included][0][attributes][attributes][storage_media] ${storage_media}
+ And Response body parameter should be: [included][0][attributes][attributes][display_technology] ${display_technology}
+ And Response body parameter should be: [included][0][attributes][attributes][brand] ${brand_4}
+ And Response body parameter should be: [included][0][attributes][attributes][color] ${color_name}
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributesDefinition] 3
+ And Response should contain the array of a certain size: [included][0][attributes][superAttributes] 1
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][super_attributes] 1
+ And Response body parameter should be: [included][0][attributes][attributeMap][product_concrete_ids] ${concrete_available_product.sku}
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][attribute_variants] 0
+ And Response should contain the array of a certain size: [included][0][attributes][attributeMap][attribute_variant_map] 1
+ And Response body parameter should be: [included][0][attributes][metaKeywords] ${concrete_available_product.meta_keywords}
+ And Response body parameter should be: [included][0][attributes][metaDescription] ${concrete_available_product.meta_description}
+ And Response body has correct self link
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/negative.robot b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/negative.robot
new file mode 100644
index 0000000..40db562
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/negative.robot
@@ -0,0 +1,42 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_point_addresses_by_wrong_url
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses
+ Then Response status code should be: 404
+ And Response should return error message: The endpoint is not found.
+
+Retrieves_a_service_point_address_by_not_existing_service_point_and_service_point_address_ids
+ When I send a GET request: /service-points/NonExistId/service-point-addresses/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_existing_service_point_and_not_existing_service_point_address_ids
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_not_existing_service_point_and_existing_service_point_address_ids
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/NonExistId/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 404
+ And Response should return error code: 5402
+ And Response should return error message: Service point address entity was not found.
+
+Retrieves_a_service_point_address_by_incorrect_url
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-point/${dynamic_service_point_uuid}/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
diff --git a/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/positive.robot b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/positive.robot
new file mode 100644
index 0000000..0bc0ab9
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_point_addresses/positive.robot
@@ -0,0 +1,21 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_a_service_point_address_by_id
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}/service-point-addresses/${dynamic_service_point_address_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [data][type] service-point-addresses
+ And Response body parameter should be: [data][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [data][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [data][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [data][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [data][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/negative.robot b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/negative.robot
new file mode 100644
index 0000000..7722010
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/negative.robot
@@ -0,0 +1,24 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_points_by_incorrect_url
+ When I send a GET request: /service-point
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
+
+Retrieves_a_service_point_by_incorrect_url
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-point/${dynamic_service_point_uuid}
+ Then Response status code should be: 404
+ And Response should return error message: Not Found
+
+Retrieves_a_service_point_by_not_existing_id
+ When I send a GET request: /service-points/NonExistId
+ Then Response status code should be: 404
+ And Response should return error code: 5401
+ And Response should return error message: Service point entity was not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/positive.robot b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/positive.robot
new file mode 100644
index 0000000..ac3ae9b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/service_points_endpoints/service_points/positive.robot
@@ -0,0 +1,179 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/steps/api_service_point_steps.robot
+Test Tags glue service-points shipment-service-points product-offer-service-points
+
+*** Test Cases ***
+Retrieves_list_of_service_points
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should NOT be empty: [data] id
+ And Each array element of array in response should NOT be empty: [data] attributes
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body should contain: "key": "${dynamic_service.service_point_key}"
+ And Response body should contain: "name": "${dynamic_service.service_point_name}"
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_filtered_by_service_type_key
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?filter[service-points.serviceTypeKey]=${dynamic_service.service_type_key}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_filtered_by_name_using_full_text_search
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?q=${dynamic_service.service_point_name}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_filtered_by_address_line_1_using_full_text_search
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?q=${dynamic_service.service_point_address_line_1}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array of a certain size: [data] 1
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+
+Retrieves_list_of_service_points_sort_by_city_asc
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?sort=city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][6][id] ${dynamic_service_point_uuid}
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_sort_by_city_desc
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?sort=-city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response should contain the array larger than a certain size: [data] 0
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body parameter should be: [data][0][id] ${dynamic_service_point_uuid}
+ And Response body has correct self link
+
+Retrieves_list_of_service_points_with_addresses_relations
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points?include=service-point-addresses&sort=-city
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property: [data] attributes
+ And Each array element of array in response should contain property with value: [data] type service-points
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] key
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response should contain the array larger than a certain size: [included] 0
+ And Each array element of array in response should contain property: [included] type
+ And Each array element of array in response should contain property: [included] id
+ And Each array element of array in response should contain property: [included] attributes
+ And Each array element of array in response should contain property: [included] links
+ And Each array element of array in response should contain property with value: [included] type service-point-addresses
+ And Each array element of array in response should contain nested property: [included] [attributes] countryIso2Code
+ And Each array element of array in response should contain nested property: [included] [attributes] address1
+ And Each array element of array in response should contain nested property: [included] [attributes] address2
+ And Each array element of array in response should contain nested property: [included] [attributes] address3
+ And Each array element of array in response should contain nested property: [included] [attributes] zipCode
+ And Each array element of array in response should contain nested property: [included] [attributes] city
+ And Each array element of array in response should contain nested property: [included] [links] self
+ And Response body parameter should be: [included][0][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [included][0][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [included][0][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [included][0][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [included][0][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [included][0][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link
+
+Retrieves_a_service_point_by_id
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response body has correct self link internal
+
+Retrieves_a_service_point_by_id_with_address_relation
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}?include=service-point-addresses
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${dynamic_service_point_address_uuid}
+ And Response body parameter should be: [included][0][attributes][countryIso2Code] ${dynamic_service.service_point_address_country}
+ And Response body parameter should be: [included][0][attributes][address1] ${dynamic_service.service_point_address_line_1}
+ And Response body parameter should be: [included][0][attributes][address2] ${dynamic_service.service_point_address_line_2}
+ And Response body parameter should be: [included][0][attributes][city] ${dynamic_service.service_point_address_city}
+ And Response body parameter should be: [included][0][attributes][zipCode] ${dynamic_service.service_point_address_zip_code}
+ And Response body has correct self link internal
+
+Retrieves_a_service_point_by_id_with_empty_address_relation
+ Create dynamic service with all data via BAPI if doesn't exist
+ Switch to Glue
+ When I send a GET request: /service-points/${dynamic_service_point_uuid}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${dynamic_service_point_uuid}
+ And Response body parameter should be: [data][type] service-points
+ And Response body parameter should be: [data][attributes][name] ${dynamic_service.service_point_name}
+ And Response body parameter should be: [data][attributes][key] ${dynamic_service.service_point_key}
+ And Response body should not contain: included
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/negative.robot b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/negative.robot
new file mode 100644
index 0000000..fd48684
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/negative.robot
@@ -0,0 +1,760 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shopping-lists marketplace-shopping-lists product bundle-products marketplace-product configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list_without_access_token
+ I send a POST request: /shopping-lists/${1st_shopping_list.id}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Add_a_concrete_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I set Headers: Authorization=3485h7
+ I send a POST request: /shopping-lists/${1st_shopping_list.id}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+ [Teardown] Run Keywords I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_to_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/shoppingListId/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Add_a_product_with_non_existing_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"sku${random}","quantity":1}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: Concrete product not found.
+ And Response should return error code: 1508
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":0}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_negaive_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":-1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_too_big_amount_of_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":99999999999999999999}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be less than 2147483647.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_abstract_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.abstract.sku}","quantity":1}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1508
+ And Response should return error message: Concrete product not found.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_sku_value_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"","quantity":1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_sku_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: sku => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_invalid_data_for_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be less than 2147483647.
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":"-7"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_shopping_list_id_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Add_a_concrete_product_to_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_with_empty_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_without_type_in_request_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+
+Update_product_to_the_shopping_list_without_access_token
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Update_product_to_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":1}}}
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Update_product_in_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Update_product_in_the_shopping_list_withot_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists//shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_quantity_of_the_product_at_the_shopping_list_to_zero
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":0}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+
+Update_product_quntity_at_the_shopping_list_to_non_digit_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":"-2"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be greater than 0.
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{"quantity":"test"}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value: [errors] detail quantity => This value should be of type integer.
+ And Array in response should contain property with value: [errors] detail quantity => This value should be less than 2147483647.
+
+Update_product_in_the_shopping_list_withot_shopping_list_item_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/ {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Update_product_in_the_shopping_list_without_quantity_in_the_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"shopping-list-items","attributes":{}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+
+Update_product_in_the_shopping_list_with_empty_request_body
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_product_at_the_shopping_list_with_empty_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"type":"","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_product_at_the_shopping_list_without_type_in_request
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId {"data":{"attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 403
+ And Response should return error code: 002
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Remove_a_product_from_the_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 401
+ And Response should return error code: 001
+ And Response reason should be: Unauthorized
+ And Response should return error message: Invalid access token.
+
+Remove_a_product_from_the_non_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1503
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list not found.
+
+Remove_a_product_with_non_existing_id_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/shoppingListItemId
+ And Response status code should be: 404
+ And Response should return error code: 1504
+ And Response reason should be: Not Found
+ And Response should return error message: Shopping list item not found.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists//shopping-list-items/shoppingListItemId
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Remove_a_product_from_the_shopping_list_without_shopping_list_item_id_in_url
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/shoppingListId/shopping-list-items/
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Remove_a_concrete_product_from_the_shared_shopping_list_without_write_access_permission
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][1][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 403
+ And Response should return error code: 1505
+ And Response reason should be: Forbidden
+ And Response should return error message: Requested operation requires write access permission.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_shopping_list_with_configuration_and_configurable_product
+ [Documentation] https://spryker.atlassian.net/browse/CC-23115
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.01\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response status code should be: 201
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_zero_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":0,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"fake","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be of type integer.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":-2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should be greater than 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_quantity_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_quantity_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":"","productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: quantity => This value should not be blank.
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should not be blank.
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_aconfigurable_product_with_string_availableQuantity_value_of_to_the_shopping_list
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":"string","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: availableQuantity => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":1,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":"True","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/positive.robot b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/positive.robot
new file mode 100644
index 0000000..55d54e3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_list_items/positive.robot
@@ -0,0 +1,500 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue shopping-lists marketplace-shopping-lists product bundle-products marketplace-product prices configurable-product configurable-product-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Add_a_concrete_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_one_more_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_the_same_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_a_bundle_concrete_product_to_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${bundle_product.concrete.product_1_sku}
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_an_unavailable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${product_availability.concrete_unavailable_product}","quantity":1}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${product_availability.concrete_unavailable_product}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_concrete_product_to_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include element has self link: concrete-products
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_a_concrete_product_at_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_quantity_of_the_bundle_concrete_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId} {"data":{"type":"shopping-list-items","attributes":{"quantity":2}}}
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][quantity] 2
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_bundle_concrete_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_concrete_product_from_the_shared_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists/
+ ... AND Response status code should be: 200
+ ... AND Save value to a variable: [data][0][id] sharedShoppingListId
+ ... AND I send a POST request: /shopping-lists/${sharedShoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListItemId
+ ... AND I get access token for the customer: ${yves_shared_shopping_list_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${sharedShoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+
+Add_a_configurable_product_to_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 3
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][type] shopping-list-items
+ And Response body parameter should be: [data][relationships][shopping-list-items][data][0][id] ${shoppingListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][id] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${shoppingListItemId}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"20.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"20.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: shopping-list-items
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"01.01.2025\"}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_the_quantity_of_the_Configured_Product_so_Volume_price_is_applied
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a PATCH request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}?include=concrete-products {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":6,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"01.01.2025\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 6
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][grossAmount] 165
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][prices][0][volumePrices][0][netAmount] 150
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":false,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${shoppingListItemId1} ${shoppingListItemId2} ${configurable_product.sku}
+ And Response body parameter should be in: [included][0][attributes][quantity] 2 1
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"}
+ And Response body parameter should be in: [included][0][attributes][productConfigurationInstance][isComplete] True False
+ And Response body parameter should be in: [included][1][id] ${shoppingListItemId2} ${shoppingListItemId1} ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][attributes][quantity] 1 2
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2040\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 3
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be: [included][0][id] ${shoppingListItemId1}
+ And Response body parameter should be: [included][0][attributes][quantity] 2
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"10.10.2040\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][1][attributes][quantity] 1
+ And Response body parameter should be: [included][1][attributes][sku] ${concrete_available_product.sku}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance] None
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":2,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId
+ And Response body parameter should be: [data][attributes][quantity] 2
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_shopping_list_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${configurable_product.sku}","quantity":1,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"10.10.2040\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":2,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId1
+ And Response body parameter should be: [data][attributes][quantity] 1
+ I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListItemId2
+ And Response body parameter should be: [data][attributes][quantity] 1
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ I send a DELETE request: /shopping-lists/${shoppingListId}/shopping-list-items/${shoppingListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${shoppingListItemId2}
+ And Response body parameter should be: [included][0][attributes][quantity] 1
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${ShoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/negative.robot b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/negative.robot
new file mode 100644
index 0000000..6278f3b
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/negative.robot
@@ -0,0 +1,233 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue shopping-lists marketplace-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Create_a_shopping_list_with_empty_type
+ I send a POST request: /shopping-lists {"data":{"type":"","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_empty_values_for_required_fields
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_non_autorized_user
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Create_a_shopping_list_with_absent_type
+ I send a POST request: /shopping-lists {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Create_a_shopping_list_with_already_existing_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value: [errors] detail Shopping list with given name already exists.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Create_a_shopping_list_with_too_long_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value is too long. It should have 255 characters or less.
+
+Delete_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a DELETE request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Delete_shopping_list_without_access_token
+ I send a DELETE request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Delete_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a DELETE request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
+
+Delete_a_shopping_list_withouth_shopping_list_id
+ I send a DELETE request: /shopping-lists
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_for_the_customer_with_empty_attribute_section
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This field is missing.
+
+Update_shopping_list_with_existing_name_of_another_available_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND Save value to a variable: [data][1][attributes][name] 2ndShoppingListName
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${2ndShoppingListName}"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 1506
+ And Array in response should contain property with value: [errors] detail Shopping list with given name already exists.
+
+Update_shopping_list_with_empty_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":""}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value should not be blank.
+
+Update_shopping_list_name_with_too_long_value
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"}}}
+ And Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Array in response should contain property with value: [errors] detail name => This value is too long. It should have 255 characters or less.
+
+Update_shopping_list_withouth_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/ {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Array in response should contain property with value: [errors] detail Resource id is not specified.
+
+Update_shopping_list_with_wrong_shopping_list_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_shopping_list_with_non_autorized_user
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Update_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Update_a_shopping_list_with_absent_type
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Post data is invalid.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Update_a_shopping_list_with_invalid_type
+ I send a PATCH request: /shopping-lists/shoppingListId {"data":{"type":"shoppinglists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Invalid type.
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_shopping_list_with_non_autorized_user
+ I send a GET request: /shopping-lists/shoppingListId
+ Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Array in response should contain property with value: [errors] detail Missing access token.
+
+Get_not_existing_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/test12345
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_of_another_customer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a GET request: /shopping-lists
+ ... AND Save value to a variable: [data][0][id] shoppingListId
+ ... AND I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 1503
+ And Array in response should contain property with value: [errors] detail Shopping list not found.
+
+Get_existing_shopping_list_with_wrong_access_token
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}1
+ I send a GET request: /shopping-lists/shoppingListId
+ And Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Array in response should contain property with value: [errors] detail Invalid access token.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/positive.robot b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/positive.robot
new file mode 100644
index 0000000..af3a03f
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/shopping_list_endpoints/shopping_lists/positive.robot
@@ -0,0 +1,218 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue shopping-lists marketplace-shopping-lists customer-access customer-account-management acl
+
+*** Test Cases ***
+Create_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] shoppingListId
+ And Save value to a variable: [data][attributes][createdAt] createdAt
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Delete_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ Log message
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ I send a PATCH request: /shopping-lists/${shoppingListId} {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Update_a_shopping_list_name_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":1}}}
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${bundle_product.concrete.product_1_sku}","quantity":1}}}
+ I send a PATCH request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}!@#$%^&*()-_"}}}
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}!@#$%^&*()-_
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data][relationships][shopping-list-items][data] [type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data][relationships][shopping-list-items][data] [id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 4
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_a_shopping_list_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND Save value to a variable: [data][attributes][createdAt] createdAt
+ ... AND Save value to a variable: [data][attributes][updatedAt] updatedAt
+ I send a GET request: /shopping-lists/${shoppingListId}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response body parameter should be: [data][id] ${shoppingListId}
+ And Response body parameter should be: [data][attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Response body parameter should be: [data][attributes][name] ${shopping_list_name}${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId1
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}2"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId2
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] type shopping-lists
+ And Each array element of array in response should contain nested property with datatype: [data] id str
+ And Each array element of array in response should contain nested property with value: [data] [attributes][owner] ${yves_user.first_name} ${yves_user.last_name}
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][name] str
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][createdAt] str
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][updatedAt] str
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId1}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+ ... AND I send a DELETE request: /shopping-lists/${shoppingListId2}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_shopping_lists_info_with_non_zero_quantity_of_number_of_items
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}1"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId1
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should NOT be: [data][0][attributes][numberOfItems] "None"
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId1}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_shopping_lists_info_for_user_with_zero_quantity_of_number_of_shopping_lists
+ [Setup] Run Keywords I get access token for the customer: ${yves_fourth_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists
+ And Response status code should be: 200
+ And Response should contain the array of a certain size: [data] 0
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+
+Get_single_shopping_list_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ ... AND I send a POST request: /shopping-lists {"data":{"type":"shopping-lists","attributes":{"name":"${shopping_list_name}${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] shoppingListId
+ ... AND I send a POST request: /shopping-lists/${shoppingListId}/shopping-list-items {"data":{"type":"shopping-list-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3}}}
+ ... AND Response status code should be: 201
+ I send a GET request: /shopping-lists/${shoppingListId}?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Save value to a variable: [data][attributes][numberOfItems] numberOfItems
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data][relationships][shopping-list-items][data] [type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data][relationships][shopping-list-items][data] [id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Response body parameter should be: [data][type] shopping-lists
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][relationships] 0
+ And Response should contain the array smaller than a certain size: [data][relationships] ${numberOfItems}+1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
+ [Teardown] Run Keywords I send a DELETE request: /shopping-lists/${shoppingListId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Get_several_shopping_lists_info_with_includes
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Content-Type=${default_header_content_type} Authorization=${token}
+ I send a GET request: /shopping-lists?include=shopping-list-items,concrete-products
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Each array element of array in response should contain nested property with value: [data] [relationships][shopping-list-items][data][0][type] shopping-list-items
+ And Each array element of array in response should contain nested property with datatype: [data] [relationships][shopping-list-items][data][0][id] str
+ And Each array element of array in response should contain nested property with datatype: [included] [type] str
+ And Each array element of array in response should contain nested property with datatype: [included] [id] str
+ And Each array element of array in response should contain nested property with value: [data] type shopping-lists
+ And Response should contain the array larger than a certain size: [included] 2
+ And Response should contain the array larger than a certain size: [data][0][relationships] 0
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: shopping-list-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: shopping-list-items
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/negative.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/negative.robot
new file mode 100644
index 0000000..5adc8a3
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/negative.robot
@@ -0,0 +1,68 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue
+
+*** Test Cases ***
+#GET requests
+
+### Precondition: To run commented tests need to enable service endpoints and uncomment tests
+### To enable the endpoints, add the following to /config/Shared/config_default.php:
+### Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+### Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+# Get_health_check_with_disabled_services
+# [Documentation] Test works only if all services are disabled as default
+# When I send a GET request: /health-check
+# Then Response status code should be: 403
+# And Response reason should be: Forbidden
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] None
+# And Response body parameter should be: [data][0][attributes][statusCode] 403
+# And Response body parameter should be: [data][0][attributes][message] HealthCheck endpoints are disabled for all applications.
+# And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+# And Response body has correct self link
+
+# Get_health_check_with_invalid_service_name
+# When I send a GET request: /health-check?services=sear
+# Then Response status code should be: 400
+# And Response reason should be: Bad Request
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] None
+# And Response body parameter should be: [data][0][attributes][statusCode] 400
+# And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+# And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+# And Response body has correct self link
+
+# Get_health_check_with_empty_service_name
+# When I send a GET request: /health-check?services=
+# Then Response status code should be: 400
+# And Response reason should be: Bad Request
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] None
+# And Response body parameter should be: [data][0][attributes][statusCode] 400
+# And Response body parameter should be: [data][0][attributes][message] Requested services not found.
+# And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 0
+# And Response body has correct self link
+
+# Get_health_check_with_non_existing_id
+# [Tags] skip-due-to-issue
+# [Documentation] The bug https://spryker.atlassian.net/browse/CC-16492 related to the self link and required ID
+# When I send a GET request: /health-check/1
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][type] health-check
+# And Response body parameter should be: [data][id] None
+# And Response body parameter should be: [data][attributes][status] healthy
+# And Response body parameter should be: [data][attributes][statusCode] 200
+# And Response body parameter should be: [data][attributes][message] None
+# And Response body parameter should be: [data][attributes][healthCheckServiceResponses][0][name] search
+# And Response body parameter should be: [data][attributes][healthCheckServiceResponses][1][name] storage
+# And Response body parameter should be: [data][attributes][healthCheckServiceResponses][2][name] zed-request
+# And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] status True
+# And Each array element of array in response should contain property with value: [data][attributes][healthCheckServiceResponses] message None
+# And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/positive.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/positive.robot
new file mode 100644
index 0000000..eb858bf
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/health_checks/positive.robot
@@ -0,0 +1,72 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue
+
+*** Test Cases ***
+# GET requests
+
+# Precondition: To run commented tests need to enable service endpoints and uncomment tests
+# To enable the endpoints, add the following to /config/Shared/config_default.php:
+# Spryker\Shared\HealthCheck\HealthCheckConstants;$config[HealthCheckConstants::HEALTH_CHECK_ENABLED] = true;
+# Doc: https://docs.spryker.com/docs/scos/dev/technical-enhancement-integration-guides/integrating-health-checks.html#general-information
+
+# Get_health_check_with_all_enabled_services
+# When I send a GET request: /health-check
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response should contain the array of a certain size: [data][0][attributes][healthCheckServiceResponses] 3
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][1][name] storage
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][2][name] zed-request
+# And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] status True
+# And Each array element of array in response should contain property with value: [data][0][attributes][healthCheckServiceResponses] message None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_search_service
+# When I send a GET request: /health-check?services=search
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] search
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_storage_service
+# When I send a GET request: /health-check?services=storage
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] storage
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
+
+# Get_health_check_with_enabled_zed_request_service
+# When I send a GET request: /health-check?services=zed-request
+# Then Response status code should be: 200
+# And Response reason should be: OK
+# And Response body parameter should be: [data][0][type] health-check
+# And Response body parameter should be: [data][0][id] None
+# And Response body parameter should be: [data][0][attributes][status] healthy
+# And Response body parameter should be: [data][0][attributes][statusCode] 200
+# And Response body parameter should be: [data][0][attributes][message] None
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][name] zed-request
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][status] True
+# And Response body parameter should be: [data][0][attributes][healthCheckServiceResponses][0][message] None
+# And Response body has correct self link
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..b2480d8
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found.
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..b151e9e
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/stores/positive.robot
@@ -0,0 +1,110 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_all_available_stores
+ [Tags] dms-off
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] timeZone
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ [Tags] dms-off
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Response body parameter should be: [data][attributes][timeZone] Europe/Berlin
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
+
+DMS_Get_all_available_stores
+ [Tags] dms-on
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+DMS_Get_store_by_id
+ [Tags] dms-on
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/negative.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/negative.robot
new file mode 100644
index 0000000..af060dc
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/negative.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_url_collection_by_empty_url
+ When I send a GET request: /url-resolver
+ Then Response status code should be: 422
+ And Response should return error code: 2801
+ And Response should return error message: Url request parameter is missing.
+
+Get_url_collection_when_requested_url_does_not_exist
+ When I send a GET request: /url-resolver?url=/requested/url/does/not/exist/
+ Then Response status code should be: 404
+ And Response should return error code: 2802
+ And Response should return error message: Url not found.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/positive.robot b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/positive.robot
new file mode 100644
index 0000000..5f4ba14
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/utility_endpoints/url_resolver/positive.robot
@@ -0,0 +1,66 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue spryker-core
+
+*** Test Cases ***
+Get_url_collections_by_url_paramater_of_category_nodes
+ When I send a GET request: /url-resolver?url=${url_resolver_category_nodes}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_category_nodes_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_category_nodes_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_product
+ When I send a GET request: /url-resolver?url=${url_resolver_abstract_product}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_product_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_product_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_cms_page
+ When I send a GET request: /url-resolver?url=${url_resolver_cms}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_cms_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_cms_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_paramater_of_merchant_page
+ When I send a GET request: /url-resolver?url=${url_resolver_merchant}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Array in response should contain property with value: [data] type url-resolver
+ And Each array element of array in response should contain property: [data] attributes
+ And Response body parameter should be: [data][0][attributes][entityType] ${url_resolver_merchant_entity}
+ And Response body parameter should be: [data][0][attributes][entityId] ${url_resolver_merchant_id}
+ And Each array element of array in response should contain nested property: [data] links self
+ And Response body has correct self link
+
+Get_url_collections_by_url_parameters_returns_id
+ [Documentation] CC-16595 API: ID is missing from url resolver.
+ [Tags] skip-due-to-issue
+ When I send a GET request: /url-resolver?url=${url_resolver_category_nodes}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver_abstract_product}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver_cms}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
+ When I send a GET request: /url-resolver?url=${url_resolver_merchant}
+ Then Response status code should be: 200
+ And Response body parameter should not be EMPTY: [data][0][id]
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/negative.robot b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/negative.robot
new file mode 100644
index 0000000..f202241
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/negative.robot
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue measurement-units product
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_unit_id
+ When I send a GET request: /product-measurement-units/fake
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 3402
+ And Response should return error message: Product measurement unit not found.
+
+Get_a_measurement_unit_with_empty
+ When I send a GET request: /product-measurement-units
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 3401
+ And Response should return error message: Product measurement unit code has not been specified.
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/positive.robot b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/positive.robot
new file mode 100644
index 0000000..1fdd161
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/product_measurement_units/positive.robot
@@ -0,0 +1,18 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Setup API_test_setup
+Test Tags glue measurement-units product
+
+*** Test Cases ***
+Get_product_measurement_unit_by_id
+ When I send a GET request: /product-measurement-units/${measurement_unit.m}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][id] ${measurement_unit.m}
+ And Response body parameter should be: [data][type] product-measurement-units
+ And Response body parameter should not be EMPTY: [data][attributes][name]
+ And Response body parameter should not be EMPTY: [data][attributes][defaultPrecision]
+ And Response body parameter should have datatype: [data][attributes][defaultPrecision] int
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/negative.robot b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/negative.robot
new file mode 100644
index 0000000..3ad77b7
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/negative.robot
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product measurement-units packaging-units marketplace-packaging-units
+
+*** Test Cases ***
+Get_a_measurement_unit_with_non_existent_sku
+ When I send a GET request: /concrete-products/fake/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_abstract_sku
+ When I send a GET request: /concrete-products/${abstract_available_product_with_stock.sku}/sales-units
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 302
+ And Response should return error message: Concrete product is not found.
+
+Get_a_measurement_unit_with_empty_sku
+ When I send a GET request: /concrete-products//sales-units
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error code: 312
+ And Response should return error message: Concrete product sku is not specified.
diff --git a/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/positive.robot b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/positive.robot
new file mode 100644
index 0000000..8a6c958
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/weight_unit_endpoints/sales_units/positive.robot
@@ -0,0 +1,43 @@
+*** Settings ***
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Resource ../../../../../../resources/common/common_api.robot
+Test Tags glue product measurement-units packaging-units marketplace-packaging-units
+
+*** Test Cases ***
+Get_sales_units_for_product_without_sales_units
+ When I send a GET request: /concrete-products/${bundle_product.concrete.product_1_sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] 0
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_sales_units
+ When I send a GET request: /concrete-products/${concrete_product.random_weight.sku}/sales-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${concrete_product.random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Each array element of array in response should contain nested property with datatype: [data] [attributes][precision] int
+ And Each array element of array in response should contain nested property with datatype in: [data] [attributes][conversion] int float
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDisplayed] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][isDefault] True False
+ And Each array element of array in response should contain property with value in: [data] [attributes][productMeasurementUnitCode] ${packaging_unit.m} ${packaging_unit.cm}
+ And Response body has correct self link
+
+Get_sales_units_for_product_with_measurement_units_include
+ When I send a GET request: /concrete-products/${concrete_product.random_weight.sku}/sales-units?include=product-measurement-units
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should contain the array of a certain size: [data] ${concrete_product.random_weight.qty_of_units}
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain property with value: [data] type sales-units
+ And Response body has correct self link
+ And Each array element of array in response should contain a nested array of a certain size: [data] [relationships] 1
+ And Response should contain the array of a certain size: [included] ${concrete_product.random_weight.qty_of_units}
+ And Response include should contain certain entity type: product-measurement-units
+ And Response include element has self link: product-measurement-units
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/negative.robot b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/negative.robot
new file mode 100644
index 0000000..699d307
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/negative.robot
@@ -0,0 +1,448 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist product marketplace-product-offer marketplace-product configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+Adding_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Adding_item_in_wishlist_by_without_Access_Token
+ When I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Adding_item_with_abstract_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.sku}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "SK123445666"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": ""}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 901
+ And Response should return error message: sku => This value should not be blank.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_after_enter_space_in_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": " "}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_invalid_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/Mywishlist/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+
+Adding_item_without_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists//wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Adding_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Adding_item_with_deactivated_item_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "Demo-SKU-Id"}}}
+ Then Response status code should be: 422
+ And Response reason should be: Unprocessable Content
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_in_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=3485h7
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${abstract_available_product_with_stock.concrete_sku}
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Deleting_item_in_wishlist_by_without_Access_Token
+ When I send a DELETE request: /wishlists/mywishlist/wishlist-items/${abstract_available_product_with_stock.concrete_sku}
+ Then Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error code: 002
+ And Response should return error message: Missing access token.
+
+Deleting_item_in_wishlist_with_empty_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+ [Teardown] Run Keywords I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_reference_id}
+ ... AND Response status code should be: 204
+
+Delete_wishlist_item_from_already_deleted_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}"} }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_reference_id
+ When I send a POST request: /wishlists/${wishlist_reference_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a DELETE request: /wishlists/${wishlist_reference_id}/wishlist-items/${abstract_available_product_with_stock.concrete_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_with_invalid_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/Mywishlist/wishlist-items/${abstract_available_product_with_stock.concrete_sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Deleting_item_without_wishilist_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists//wishlist-items/${abstract_available_product_with_stock.concrete_sku}
+ Then Response status code should be: 400
+ And Response reason should be: Bad Request
+ And Response should return error message: Resource id is not specified.
+
+Deleting_items_in_wishlist_by_another_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_item_id
+ ... AND I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${wishlist_item_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+ [Teardown] Run Keywords I get access token for the customer: ${yves_second_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Deleting_concrete_product_by_abstract_product_sku
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_available_product_with_stock.concrete_sku}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${abstract_available_product_with_stock.sku}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 208
+ And Response should return error message: No item with provided sku in wishlist.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_non-configurable_product_to_the_wishlist_with_configuration_and_configurable_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${concrete_available_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 206
+ And Response should return error message: "Cant add an item."
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_item_id2
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [included][1][id] ${ wishlist_item_id2}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should not be blank."
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+
+Add_aconfigurable_product_with_missing_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This field is missing."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_availableQuantity_value_of_to_the_wishlist
+ [Documentation] https://spryker.atlassian.net/browse/CC-25381
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":"test","prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: "availableQuantity => This value should be of type numeric."
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_numeric_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":1,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_string_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":"True","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This value should be of type boolean.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_missing_isComplete_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response should return error message: productConfigurationInstance.isComplete => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_negative_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":-23434,"grossAmount":-42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be greater than or equal to 0.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be greater than or equal to 0.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_with_empty_price_value_of_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","netAmount":"","grossAmount":"","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This value should be of type numeric.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should not be blank.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This value should be of type numeric.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_a_configurable_product_to_the_wishlist_with_missing_price
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":3,"prices":[{"priceTypeName":"DEFAULT","currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.netAmount => This field is missing.
+ And Array in response should contain property with value:
+ ... [errors]
+ ... detail
+ ... productConfigurationInstance.prices.0.grossAmount => This field is missing.
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
diff --git a/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/positive.robot b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/positive.robot
new file mode 100644
index 0000000..02bea3c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlist_items/positive.robot
@@ -0,0 +1,362 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist product marketplace-product-offer marketplace-product prices configurable-product configurable-product-wishlist customer-access customer-account-management acl
+
+*** Test Cases ***
+Adding_item_in_wishlist
+ [Documentation] CC-16555 API: JSON response is missing product availability and price
+ [Tags] skip-due-to-issue
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_product_with_merchant.concrete_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantReference]
+ And Response body parameter should be: [data][attributes][productOfferReference] None
+ And Response body parameter should be: [data][type] wishlist-items
+ And Response body parameter should be: [data][id] ${wishlist_items_id}
+ And Response body parameter should be: [data][attributes][sku] ${abstract_product_with_merchant.concrete_sku}
+ And Response body parameter should be: [data][attributes][id] ${wishlist_items_id}
+ And Response body parameter should not be EMPTY: [data][attributes][availability]
+ And Response body parameter should not be EMPTY: [data][attributes][prices]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Post
+Adding_item_in_wishlist_with_offer
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_offer}", "productOfferReference": "offer37"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And Response body parameter should not be EMPTY: [data][attributes][merchantReference]
+ And Response body parameter should not be EMPTY: [data][attributes][productOfferReference]
+ And Response body parameter should be: [data][type] wishlist-items
+ And Response body parameter should be: [data][id] ${wishlist_items_id}
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.with_offer}
+ And Response body parameter should be: [data][attributes][id] ${wishlist_items_id}
+ And Response body parameter should not be EMPTY: [data][attributes][availability]
+ And Response body parameter should not be EMPTY: [data][attributes][prices]
+ And Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+
+Adding_multiple_variant_of_abstract_product_in_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_product_with_variants.variant1_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${abstract_product_with_variants.variant2_sku}"}}}
+ Then Response status code should be: 201
+ And Response reason should be: Created
+ And Save value to a variable: [data][id] wishlist_items_id
+ And Response body parameter should not be EMPTY: [data][attributes][sku]
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][1]
+ And Response body has correct self link internal
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+#Delete
+Deleting_item_from_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_offer}"}}}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ When I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${concrete_available_product.with_offer}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Add_a_configurable_product_to_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "${wishlist_name}${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][type] wishlist-items
+ And Response body parameter should be: [data][relationships][wishlist-items][data][0][id] ${WishListItemId}
+ And Response should contain the array of a certain size: [included] 2
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][0][type] concrete-products
+ And Response body parameter should be: [included][1][type] wishlist-items
+ And Response body parameter should be: [included][1][id] ${WishListItemId}
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_time_of_the_day_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "update-config-product-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][id] ${WishListItemId}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Evening\\\",\\\"Date\\\":\\\"9.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Evening\",\"Date\":\"9.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Change_preferred_date_of_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "update-date-config-product-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"09.09.2050\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"09.09.2050\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"10.10.2030\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"10.10.2030\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Set_configuration_for_the_configurable_product_in_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "configurate-product-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be: [data][attributes][productConfigurationInstance][isComplete] False
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 2
+ And Response should contain the array of a certain size: [data][relationships] 1
+ And Response include should contain certain entity type: wishlist-items
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][isComplete] True
+ And Response body parameter should be: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.11.2029\"}
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_2_Configurable_products_but_with_different_configurations
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "2-config-products-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.12.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId2
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 3
+ And Response body parameter should be in: [included][0][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][0][id] ${WishListItemId} ${WishListItemId2} ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][1][id] ${WishListItemId} ${WishListItemId2} ${configurable_product.sku}
+ And Response body parameter should be: [included][1][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"} {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"}
+ And Response body parameter should be in: [included][1][attributes][productConfigurationInstance][isComplete] False True
+ And Response body parameter should be in: [included][2][type] concrete-products wishlist-items
+ And Response body parameter should be in: [included][2][id] ${WishListItemId} ${WishListItemId2} ${configurable_product.sku}
+ And Response body parameter should be: [included][2][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be in: [included][2][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Morning\",\"Date\":\"11.12.2029\"} {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be in: [included][2][attributes][productConfigurationInstance][isComplete] False True
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_without_configurations_and_set_configuration
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "no-configurations-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":false,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][type] wishlist-items
+ And Response body parameter should be: [included][0][id] ${WishListItemId}
+ And Response body parameter should be: [included][0][attributes][sku] ${configurable_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][displayData] {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] False
+ And Response include element has self link: wishlist-items
+ I send a PATCH request: /wishlists/${ wishlist_id}/wishlist-items/${WishListItemId}?include=concrete-products {"data":{"type":"wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Morning\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"${productConfigurationInstance.configuratorKey}","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 200
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance][isComplete] True
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Add_Configurable_products_and_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "product-mix-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.sku}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 2
+ And Response should contain the array of a certain size: [included] 2
+ And Response body parameter should be in: [included][0][id] ${WishListItemId} ${wishlist_items_id2}
+ And Response body parameter should be in: [included][0][attributes][sku] ${configurable_product.sku} ${concrete_available_product.sku}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] displayData {\"Preferred time of the day\":\"Afternoon\",\"Date\":\"11.11.2029\"}
+ And Nested array element should contain sub-array with property and value at least once: [included] [attributes] [productConfigurationInstance] isComplete True
+ And Response body parameter should be in: [included][1][id] ${WishListItemId} ${wishlist_items_id2}
+ And Response body parameter should be in: [included][1][attributes][sku] ${configurable_product.sku} ${concrete_available_product.sku}
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "remove-product-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Remove_a_configurable_product_from_the_wishlist_and_leave_a_regular_product
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": { "type": "wishlists","attributes": { "name": "remove-one-product-${random}" } }}
+ ... AND Response status code should be: 201
+ ... AND Response reason should be: Created
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes":{"sku":"${configurable_product.sku}","quantity":3,"productConfigurationInstance":{"displayData":"{\\\"Preferred time of the day\\\":\\\"Afternoon\\\",\\\"Date\\\":\\\"11.11.2029\\\"}","configuration":"{\\\"time_of_day\\\":\\\"4\\\"}","configuratorKey":"DATE_TIME_CONFIGURATOR","isComplete":true,"quantity":3,"availableQuantity":4,"prices":[{"priceTypeName":"DEFAULT","netAmount":23434,"grossAmount":42502,"currency":{"code":"EUR","name":"Euro","symbol":"€"},"volumePrices":[{"netAmount":150,"grossAmount":165,"quantity":5},{"netAmount":145,"grossAmount":158,"quantity":10},{"netAmount":140,"grossAmount":152,"quantity":20}]}]}}}}
+ And Response status code should be: 201
+ And Save value to a variable: [data][id] WishListItemId1
+ And Response body parameter should be: [data][attributes][sku] ${configurable_product.sku}
+ When I send a POST request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.sku}"}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [data][id] wishlist_items_id2
+ And Response body parameter should be: [data][attributes][sku] ${concrete_available_product.sku}
+ I send a DELETE request: /wishlists/${wishlist_id}/wishlist-items/${WishListItemId1}
+ And Response status code should be: 204
+ And Response reason should be: No Content
+ And I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ And Response status code should be: 200
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response should contain the array of a certain size: [included] 1
+ And Response body parameter should be: [included][0][id] ${concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][sku] ${concrete_available_product.sku}
+ And Response body parameter should be: [included][0][attributes][productConfigurationInstance] None
+ And Response include element has self link: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/negative.robot b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/negative.robot
new file mode 100644
index 0000000..31ac997
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/negative.robot
@@ -0,0 +1,60 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist customer-access customer-account-management customer-access customer-account-management acl
+
+*** Test Cases ***
+#Get_request
+Getting_wishlist_by_invalid_Access_Token
+ [Setup] I set Headers: Authorization=abc
+ When I send a GET request: /wishlists
+ Then Response status code should be: 401
+ And Response reason should be: Unauthorized
+ And Response should return error code: 001
+ And Response should return error message: Invalid access token.
+
+Getting_wishlist_without_Access_Token
+ [Setup] I set Headers: Authorization=
+ When I send a GET request: /wishlists
+ And Response should return error code: 002
+ And Response status code should be: 403
+ And Response reason should be: Forbidden
+ And Response should return error message: Missing access token.
+
+Getting_wishlist_with_invalid_id
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ When I send a GET request: /wishlists/2345hasd
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 201
+ And Response should return error message: "Cant find wishlist."
+
+Creating_wishlist_with_missing_name
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": ""}}}
+ And Response status code should be: 422
+ And Response should return error code: 901
+ And Response reason should be: Unprocessable Content
+
+Creating_wishlist_with_space_in_name
+ Run Keywords I GET access token for the customer: ${yves_second_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": " "}}}
+ And Response status code should be: 400
+ And Response should return error code: 210
+ And Response should return error message: Please enter name using only letters, numbers, underscores, spaces or dashes.
+
+Creating_Wishlist_with_a_name_that_already_exists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${wishlist_name}"}}}
+ Then Response status code should be: 400
+ And Response should return error message: A wishlist with the same name already exists.
+ AND Response should return error code: 202
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/positive.robot b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/positive.robot
new file mode 100644
index 0000000..e22e53c
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/glue/wishlist_endpoints/wishlists/positive.robot
@@ -0,0 +1,181 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags glue wishlist marketplace-wishlist customer-access customer-account-management customer-access customer-account-management acl
+
+*** Test Cases ***
+Create_a_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ I send a POST request: /wishlists {"data":{"type":"wishlists","attributes":{"name":"${random}"}}}
+ And Response status code should be: 201
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][id] wishlistId
+ And Response body parameter should be: [data][id] ${wishlistId}
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 0
+ And Save value to a variable: [data][attributes][createdAt] createdAt
+ And Save value to a variable: [data][attributes][updatedAt] updatedAt
+ And Response body parameter should be: [data][attributes][createdAt] ${createdAt}
+ And Response body parameter should be: [data][attributes][updatedAt] ${updatedAt}
+ AND Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlistId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+#Get_Request
+Retrieves_wishlists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a POST request: /wishlists {"data":{"type":"wishlists","attributes":{"name":"${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a GET request: /wishlists
+ Then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response body parameter should not be EMPTY: [links][self]
+ And Each array element of array in response should contain property with value: [data] type wishlists
+ And Each array element of array in response should contain nested property: [data] [attributes] name
+ And Each array element of array in response should contain nested property: [data] [attributes] numberOfItems
+ And Each array element of array in response should contain property with value NOT in: [data] [links][self] None
+ And Each array element of array in response should contain property with value NOT in: [data] [id] None
+
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlistId}
+ ... AND Response status code should be: 204
+ ... AND Response reason should be: No Content
+
+Getting_wishlists_for_customer_with_no_wishlists
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ When I send a GET request: /wishlists
+ Then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response should contain the array of a certain size: [data] 0
+ AND Response body has correct self link
+
+Retrieves_wishlist_data_by_id
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ AND Response body parameter should be: [data][type] wishlists
+ AND Response body parameter should be: [data][attributes][name] ${random}
+ AND Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ AND Response body parameter should not be EMPTY: [data][id]
+ AND Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ AND Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ AND Response body parameter should not be EMPTY: [data][links][self]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Retrieves_wishlist_with_items
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0][id]
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+
+Updates_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "himanshupal"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlist_id
+ When I send a PATCH request: /wishlists/${wishlist_id} {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ AND Response body parameter should be: [data][attributes][name] ${random}
+ AND Response body parameter should be: [data][type] wishlists
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Removes_customer_wishlist
+ [Setup] Run Keywords I get access token for the customer: ${yves_user.email}
+ ... AND I set Headers: Authorization=${token}
+ ... AND I send a POST request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Response status code should be: 201
+ ... AND Save value to a variable: [data][id] wishlists_id
+ When I send a DELETE request: /wishlists/${wishlists_id}
+ Then Response status code should be: 204
+ And Response reason should be: No Content
+ When I send a GET request: /wishlists/${wishlists_id}
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+
+Wishlist_Product_Labels
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products,product-labels
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Save value to a variable: [data][attributes][name] wishlist_name
+ And Save value to a variable: [data][id] wishlist_id
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be greater than: [data][attributes][numberOfItems] -1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ And Response include element has self link: product-labels
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
+
+Retrieves_wishlist_with_items_including_concrete_products
+ [Setup] Run Keywords I GET access token for the customer: ${yves_user.email}
+ ... AND I set headers: authorization=${token}
+ ... AND I send a Post request: /wishlists {"data": {"type": "wishlists","attributes": {"name": "${random}"}}}
+ ... AND Save value to a variable: [data][id] wishlist_id
+ ... AND Response status code should be: 201
+ ... AND I send a Post request: /wishlists/${wishlist_id}/wishlist-items {"data": {"type": "wishlist-items","attributes": {"sku": "${concrete_available_product.with_label}"}}}
+ ... AND Response status code should be: 201
+ when I send a GET request: /wishlists/${wishlist_id}?include=wishlist-items,concrete-products
+ then Response status code should be: 200
+ AND Response reason should be: OK
+ And Response body has correct self link internal
+ And Response body parameter should be: [data][type] wishlists
+ And Response body parameter should be: [data][attributes][name] ${random}
+ And Response body parameter should be: [data][attributes][numberOfItems] 1
+ And Response body parameter should be: [data][id] ${wishlist_id}
+ And Response body parameter should not be EMPTY: [data][relationships]
+ And Response body parameter should not be EMPTY: [data][relationships][wishlist-items][data][0]
+ AND Response body parameter should not be EMPTY: [data][attributes][createdAt]
+ AND Response body parameter should not be EMPTY: [data][attributes][updatedAt]
+ And Response include element has self link: wishlist-items
+ And Response include element has self link: concrete-products
+ And Response should contain the array larger than a certain size: [included] 1
+ And Response include should contain certain entity type: concrete-products
+ And Response include should contain certain entity type: wishlist-items
+ [Teardown] Run Keywords I send a DELETE request: /wishlists/${wishlist_id}
+ ... AND Response status code should be: 204
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/negative.robot b/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/negative.robot
new file mode 100644
index 0000000..d2d1d89
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/negative.robot
@@ -0,0 +1,15 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Get_store_by_non_exist_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/NON_EXIST_STORE
+ Then Response status code should be: 404
+ And Response reason should be: Not Found
+ And Response should return error code: 601
+ And Response header parameter should be: Content-Type ${default_header_content_type}
+ And Response should return error message: Store not found
diff --git a/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/positive.robot b/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/positive.robot
new file mode 100644
index 0000000..400d6e0
--- /dev/null
+++ b/atest/testdata/performance/tests/api/suite/sapi/utility_endpoints/stores/positive.robot
@@ -0,0 +1,56 @@
+*** Settings ***
+Resource ../../../../../../resources/common/common_api.robot
+Suite Setup API_suite_setup
+Test Setup API_test_setup
+Test Tags sapi spryker-core spryker-core-back-office
+
+*** Test Cases ***
+Get_all_availiable_stores
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Each array element of array in response should contain property: [data] type
+ And Each array element of array in response should contain property: [data] id
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of array in response should contain nested property: [data] [attributes] currencies
+ And Each array element of array in response should contain nested property: [data] [attributes] locales
+ And Each array element of array in response should contain nested property: [data] [attributes] countries
+ And Each array element of array in response should contain nested property: [data] [attributes] defaultCurrency
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of nested array should contain property with value in: [data] [attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] code
+ And Each array element of array in response should contain nested property: [data] [attributes][currencies] name
+ And Each array element of nested array should contain property with value in: [data] [attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain nested property: [data] [attributes][locales] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso2Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] iso3Code
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] name
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain nested property: [data] [attributes][countries] postalCodeRegex
+ And Each array element of array in response should contain nested property: [data] [links] self
+ And Response body has correct self link
+
+Get_store_by_id
+ And I set Headers: Content-Type=${default_header_content_type}
+ When I send a GET request: /stores/${store.de}
+ Then Response status code should be: 200
+ And Response reason should be: OK
+ And Response body parameter should be: [data][type] stores
+ And Response body parameter should be: [data][id] ${store.de}
+ And Response body parameter should not be EMPTY: [data][attributes]
+ And Response body parameter should have datatype: [data][attributes][currencies] list
+ And Response body parameter should have datatype: [data][attributes][locales] list
+ And Response body parameter should have datatype: [data][attributes][countries] list
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] name ${currency.eur.name} ${currency.dollar.name} ${currency.chf.name}
+ And Each array element of array in response should contain property with value in: [data][attributes][currencies] code ${currency.eur.code} ${currency.dollar.code} ${currency.chf.code}
+ And Each array element of array in response should contain property: [data][attributes][currencies] name
+ And Each array element of array in response should contain property: [data][attributes][currencies] code
+ And Each array element of array in response should contain property with value in: [data][attributes][locales] name ${locale.DE.name} ${locale.EN.name}
+ And Each array element of array in response should contain property: [data][attributes][locales] name
+ And Each array element of array in response should contain property: [data][attributes][countries] iso2Code
+ And Each array element of array in response should contain property: [data][attributes][countries] iso3Code
+ And Each array element of array in response should contain property: [data][attributes][countries] name
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeMandatory
+ And Each array element of array in response should contain property: [data][attributes][countries] postalCodeRegex
+ And Response body has correct self link internal
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/administration/administration.robot b/atest/testdata/performance/tests/parallel_ui/b2b/administration/administration.robot
new file mode 100644
index 0000000..2b7e957
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/administration/administration.robot
@@ -0,0 +1,50 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/zed_root_menus_steps.robot
+Resource ../../../../resources/steps/glossary_steps.robot
+
+*** Test Cases ***
+Zed_navigation_ordering_and_naming
+ [Documentation] Verifies each left navigation node can be opened
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: verify first navigation root menus
+ Zed: verify root menu icons
+ Zed: verify second navigation root menus
+ [Teardown] Delete dynamic admin user from DB
+
+Glossary
+ [Documentation] Create + edit glossary translation in BO
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click button in Header: Create Translation
+ Zed: fill glossary form:
+ ... || Name | EN_US | DE_DE ||
+ ... || cart.price.test${random} | This is a sample translation | Dies ist eine Beispielübersetzung ||
+ Zed: submit the form
+ Zed: table should contain: cart.price.test${random}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click Action Button in a table for row that contains: ${glossary_name} Edit
+ Zed: fill glossary form:
+ ... || DE_DE | EN_US ||
+ ... || ${original_DE_text}-Test | ${original_EN_text}-Test-${random} ||
+ Zed: submit the form
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}-Test-${random}
+ Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}
+ [Teardown] Run Keywords Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ ... AND Trigger p&s
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog.robot b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog.robot
new file mode 100644
index 0000000..b35c10d
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog.robot
@@ -0,0 +1,309 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+*** Test Cases ***
+Quick_Order
+ [Documentation] Checks Quick Order, checkout and Reorder
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping List' with name: quickOrderList+${random}
+ Yves: go to 'Quick Order' page through the header
+ Yves: 'Quick Order' page is displayed
+ Yves: add the following articles into the form through quick order text area: 401627,1\n520561,3\n421340,21\n419871,1\n419869,11\n425073,1\n425084,2
+ Yves: add products to the shopping cart from quick order page
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 401627 520561 421340 419871 419869 425073 425084
+ Yves: go to 'Quick Order' page through the header
+ Yves: add the following articles into the form through quick order text area: 401627,1\n520561,3\n421340,21\n419871,1\n419869,11\n425073,1\n425084,2
+ Yves: add products to the shopping list from quick order page with name: quickOrderList+${random}
+ Yves: 'Shopping List' page is displayed
+ Yves: shopping list contains the following products: 401627 520561 421340 419871 419869 425073 425084
+ Yves: go to shopping cart page
+ ### Order placement ###
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ ### Order History ###
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ ### Reorder ###
+ Yves: reorder all items from 'Order Details' page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 401627 520561 421340 419871 419869 425073 425084
+
+Discontinued_Alternative_Products
+ [Documentation] Checks that product can be discontinued in Zed.
+ [Setup] Create dynamic admin user in DB
+ Yves: go to PDP of the product with sku: M21100
+ Yves: PDP contains/doesn't contain: true ${alternativeProducts}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | name en | name de | new from | new to ||
+ ... || discontinuedSKU${random} | DE | discontinuedProduct${random} | DEdiscontinuedProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 ||
+ ... || farbe | grey ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Standard Taxes ||
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || discontinuedSKU${random} | discontinuedSKU${random}-farbe-grey | true | true | true ||
+ Zed: add following alternative products to the concrete: M22613
+ Zed: concrete product has the following alternative products: M22613
+ Zed: discontinue the following product: discontinuedSKU${random} discontinuedSKU${random}-farbe-grey
+ Zed: product is successfully discontinued
+ [Teardown] Delete dynamic admin user from DB
+
+Measurement_Units
+ [Documentation] Checks checkout with Measurement Unit product
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M23723
+ Yves: select the following 'Sales Unit' on PDP: Meter
+ Yves: change quantity using '+' or '-' button № times: + 1
+ Yves: PDP contains/doesn't contain: true ${measurementUnitSuggestion}
+ Yves: change quantity using '+' or '-' button № times: - 1
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1006871
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 425079
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Packaging_Units
+ [Documentation] Checks checkout with Packaging Unit product
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M21766
+ Yves: change variant of the product on PDP on: Box
+ Yves: change amount on PDP: 51
+ Yves: PDP contains/doesn't contain: true ${packagingUnitSuggestion}
+ Yves: change amount on PDP: 10
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1006871
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: 421519_3
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Product_Bundles
+ [Documentation] Checks checkout with Bundle product
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${bundleItemsSmall}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: ${bundle_product_concrete_sku}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ [Teardown] Delete dynamic admin user from DB
+
+Product_Restrictions
+ [Documentation] Checks White and Black lists
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_restriction_customer_email_1}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_restriction_customer_email_2}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: Soennecken
+ Yves: 'Catalog' page should show products: 18
+ Yves: go to URL: en/office-furniture/storage/lockers
+ Yves: 'Catalog' page should show products: 34
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: perform search by: Soennecken
+ Yves: 'Catalog' page should show products: 0
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_third_customer}
+ Yves: go to URL: en/office-furniture/storage/lockers
+ Yves: 'Catalog' page should show products: 0
+ Yves: go to URL: en/transport/lift-carts
+ Yves: 'Catalog' page should show products: 16
+ Yves: go to URL: en/transport/sack-trucks
+ Yves: 'Catalog' page should show products: 10
+
+Product_PDP
+ [Documentation] Checks that PDP contains required elements
+ [Setup] Create dynamic customer in DB
+ Delete All Cookies
+ Yves: go to PDP of the product with sku: ${multi_variant_product_abstract_sku}
+ Yves: change variant of the product on PDP on: 500 x 930 x 400
+ Yves: PDP contains/doesn't contain: true ${pdp_warranty_option} ${pdp_insurance_option}
+ Yves: PDP contains/doesn't contain: false ${pdpPriceLocator} ${addToCartButton}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${multi_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${pdp_add_to_cart_disabled_button}[${env}] ${pdp_warranty_option} ${pdp_insurance_option}
+ Yves: change variant of the product on PDP on: 500 x 930 x 400
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton} ${pdp_warranty_option} ${pdp_insurance_option}
+
+Catalog
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Trigger product labels update
+ [Documentation] Checks that catalog options and search work
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: claire
+ Yves: 'Catalog' page should show products: 15
+ Yves: catalog page contains filter: Product Ratings Product Labels Brand Color
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 1
+ Yves: go to first navigation item level: Stationery
+ Yves: 'Catalog' page should show products: 114
+ Yves: page contains CMS element: CMS Block Build a Space That Spurs Creativity
+ Yves: page contains CMS element: CMS Block Tackle Your To-Do's
+ Yves: change sorting order on catalog page: Sort by price ascending
+ Yves: 1st product card in catalog (not)contains: Price 0.48
+ Yves: change sorting order on catalog page: Sort by price descending
+ Yves: 1st product card in catalog (not)contains: Price €41.68
+ Yves: go to catalog page: 2
+ Yves: catalog page contains filter: Product Ratings Product Labels Brand Color
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 3
+
+Catalog_Actions
+ [Documentation] Checks quick add to cart and product groups
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: Verbatim USB stick OTG
+ Yves: 1st product card in catalog (not)contains: Add to Cart true
+ Yves: quick add to cart for first item in catalog
+ Yves: perform search by: New Clairefontaine Collegeblock 8272C DIN A5, 90 sheets
+ Yves: 1st product card in catalog (not)contains: Add to Cart false
+ Yves: perform search by: ${multi_color_product_abstract_sku}
+ Yves: 1st product card in catalog (not)contains: Add to Cart true
+ Yves: 1st product card in catalog (not)contains: Color selector true
+ Yves: mouse over color on product card: Blue
+ Yves: quick add to cart for first item in catalog
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: 420573 107255
+
+Back_in_Stock_Notification
+ [Documentation] Back in stock notification is sent and availability check
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} false 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} false
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} false
+ Yves: submit back in stock notification request for email: ${dynamic_customer}
+ Yves: unsubscribe from availability notifications
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} true 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} true
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} true
+ [Teardown] Run Keywords Zed: check and restore product availability in Zed: ${stock_product_abstract_sku} Available ${stock_product_concrete_sku} ${dynamic_admin_user}
+ ... AND Delete dynamic admin user from DB
+
+Configurable_Product_PDP_Shopping_List
+ [Documentation] Configure products from both the PDP and the Shopping List. Verify the availability of five items. Ensure that products that have not been configured cannot be purchased.
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Yves: login on Yves with provided credentials: ${dynamic_customer}
+ ... AND Yves: create new 'Shopping List' with name: configProduct+${random}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: checkout is blocked with the following message: This cart can't be processed. Please configure items inside the cart.
+ Yves: delete product from the shopping cart with sku: ${configurable_product_concrete_sku}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: check and go back that configuration page contains:
+ ... || store | locale | price_mode | currency | customer_id | sku ||
+ ... || DE | en_US | GROSS_MODE | EUR | ${yves_company_user_buyer_reference} | ${configurable_product_concrete_sku} ||
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 240 ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 480 ||
+ Yves: product configuration notification is: Only 7 items available
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 5 shelves | 3 lockers ||
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: change quantity on PDP: 8
+ Yves: try add product to the cart from PDP and expect error: Item ${configurable_product_concrete_sku} only has availability of 7.
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change quantity on PDP: 7
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 140 | 240 ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: ${configurable_product_concrete_sku} ${configurable_product_name} €2,206.54
+ Yves: delete all shopping carts
+ Yves: create new 'Shopping Cart' with name: configProduct+${random}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: add product to the shopping list: configProduct+${random}
+ Yves: go to 'Shopping Lists' page
+ Yves: view shopping list with name: configProduct+${random}
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 240 ||
+ Yves: save product configuration
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 6 shelves | 2 lockers ||
+ Yves: add all available products from list to cart
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 6 shelves | 2 lockers ||
+ Yves: shopping cart contains product with unit price: ${configurable_product_concrete_sku} ${configurable_product_name} €2,486.54
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_configurable_product.robot b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_configurable_product.robot
new file mode 100644
index 0000000..acde1b7
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_configurable_product.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common_ui.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Configurable_Product_RfQ_OMS
+ [Documentation] Conf Product in RfQ, OMS, Merchant OMS and reorder.
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 480 ||
+ Yves: save product configuration
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: submit new request for quote
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: go to 'Agent Quote Requests' page through the header
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Waiting
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page is displayed
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: click 'Edit Items' button on the 'Quote Request Details' page
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 240 ||
+ Yves: save product configuration
+ Yves: click 'Save and Back to Edit' button on the 'Quote Request Details' page
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Convert to Cart' button on the 'Quote Request Details' page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €2,352.44
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: Ship
+ Zed: trigger all matching states inside this order: Stock update
+ Zed: trigger all matching states inside this order: Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Order History
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order
+ Yves: 'Order Details' page is displayed
+ ### Reorder ###
+ Yves: reorder all items from 'Order Details' page
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: product configuration status should be equal: Configuration is not complete.
+ [Teardown] Delete dynamic admin user from DB
+
+Configurable_Product_Checkout
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 140 | 480 ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_sku} productName=${configurable_product_name} productPrice=2,306.54
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 240 ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_sku} productName=${configurable_product_name} productPrice=2,346.54
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €2,352.44
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_manage_product.robot b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_manage_product.robot
new file mode 100644
index 0000000..c6749ac
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_manage_product.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Manage_Product
+ [Documentation] checks that BO user can manage abstract and concrete products + create new
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | name en | name de | new from | new to ||
+ ... || manageSKU${random} | DE | manageProduct${random} | DEmanageProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 | attribute 2 | attribute value 2 ||
+ ... || farbe | grey | farbe | blue ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-grey | true | true | true ||
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-blue | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-blue | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-grey | Warehouse1 | 100 | true ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-blue | Warehouse1 | 100 | false ||
+ Zed: save abstract product: manageSKU${random}
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || manageSKU${random} | DEmanageProduct${random} force ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: manageSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change variant of the product on PDP on: grey
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: blue
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: add new concrete product to abstract:
+ ... || productAbstract | sku | autogenerate sku | attribute 1 | name en | name de | use prices from abstract ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-black | false | black | ENaddedConcrete${random} | DEaddedConcrete${random} | true ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-black | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-black | DE | gross | default | € | 25.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-farbe-black | Warehouse1 | 5 | false ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || manageSKU${random} | DE | gross | default | € | 150.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || manageSKU${random} | DE | gross | default | € | 150.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name en | name de ||
+ ... || manageSKU${random} | ENUpdatedmanageProduct${random} | DEUpdatedmanageProduct${random} ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: manageSKU${random} wait_for_p&s=true
+ Yves: product name on PDP should be: ENUpdatedmanageProduct${random}
+ Yves: product price on the PDP should be: €150.00 wait_for_p&s=true
+ Yves: change variant of the product on PDP on: grey
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: blue
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: black
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product name on PDP should be: ENaddedConcrete${random}
+ Yves: product price on the PDP should be: €25.00 wait_for_p&s=true
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item manageSKU${random}-farbe-black only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: manageSKU${random}-farbe-black ENaddedConcrete${random} 25.00
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: manageProduct${random} View
+ Zed: view product page is displayed
+ Zed: view abstract product page contains:
+ ... || store | sku | name | variants count ||
+ ... || DE AT | manageSKU${random} | ENUpdatedmanageProduct${random} | 3 ||
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_prices.robot b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_prices.robot
new file mode 100644
index 0000000..4cbef6e
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_prices.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+
+*** Test Cases ***
+Volume_Prices
+ [Documentation] Checks that volume prices are applied in cart
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M21189
+ Yves: change quantity on PDP: 5
+ Yves: product price on the PDP should be: €4.20
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 420685 Post-it stick note Super Sticky Meeting Notes 6445-4SS 4 pieces/pack 4.20
+
+Customer_Specific_Prices
+ [Documentation] Checks that product price can be different for different customers
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_special_prices_customer_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: ${one_variant_product_abstract_name}
+ Yves: product with name in the catalog should have price: ${one_variant_product_abstract_name} ${one_variant_product_default_price}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: product price on the PDP should be: ${one_variant_product_default_price}
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: perform search by: ${one_variant_product_abstract_name}
+ Yves: product with name in the catalog should have price: ${one_variant_product_abstract_name} ${one_variant_product_merchant_price}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: product price on the PDP should be: ${one_variant_product_merchant_price}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 188.34
+
+Product_Original_Price
+ [Documentation] checks that Original price is displayed on the PDP and in Catalog
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | name en | name de | new from | new to ||
+ ... || originalSKU${random} | DE | originalProduct${random} | DEoriginalProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 | attribute 2 | attribute value 2 ||
+ ... || farbe | grey | farbe | blue ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Standard Taxes ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | original | € | 200.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-grey | true | true | true ||
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-blue | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-blue | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-blue | DE | gross | original | € | 50.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-grey | Warehouse1 | 100 | true ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || originalSKU${random} | originalSKU${random}-farbe-blue | Warehouse1 | 100 | false ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || originalSKU${random} | originalSKU${random} forced ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/search?q=originalSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 2 5s
+ Yves: 1st product card in catalog (not)contains: Price €100.00
+ Yves: 1st product card in catalog (not)contains: Original Price €200.00
+ Yves: go to PDP of the product with sku: originalSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: product original price on the PDP should be: €200.00
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change variant of the product on PDP on: blue
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: product original price on the PDP should be: €50.00
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_product_availability.robot b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_product_availability.robot
new file mode 100644
index 0000000..3169c98
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/catalog/catalog_product_availability.robot
@@ -0,0 +1,109 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Product_Availability_Calculation
+ [Documentation] Check product availability + multistore
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Warehouse1 | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: start new abstract product creation:
+ ... || sku | store | store 2 | name en | name de | new from | new to ||
+ ... || availabilitySKU${random} | DE | AT | availabilityProduct${random} | DEavailabilityProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 ||
+ ... || farbe | grey ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Standard Taxes ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || AT | gross | default | € | 200.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-farbe-grey | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-farbe-grey | DE | gross | default | € | 50.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-farbe-grey | AT | gross | default | € | 75.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-farbe-grey | Warehouse1 | 5 | false ||
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || availabilitySKU${random} | DEavailabilityProduct${random} force ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-farbe-grey only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: wait for order item to be in state: sku=availabilitySKU${random}-farbe-grey state=payment pending iterations=7
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-farbe-grey only has availability of 2.
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: Cancel
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-farbe-grey only has availability of 5.
+ Yves: go to AT store 'Home' page if other store not specified:
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update warehouse:
+ ... || warehouse | unselect store ||
+ ... || Warehouse1 | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to AT store 'Home' page if other store not specified:
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: update warehouse:
+ ... || warehouse | unselect store ||
+ ... || Warehouse1 | AT ||
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/checkout/checkout.robot b/atest/testdata/performance/tests/parallel_ui/b2b/checkout/checkout.robot
new file mode 100644
index 0000000..21c1102
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/checkout/checkout.robot
@@ -0,0 +1,324 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/order_comments_steps.robot
+
+*** Test Cases ***
+Business_Unit_Address_on_Checkout
+ [Documentation] Checks that business unit address can be used during checkout
+ [Setup] Create dynamic customer in DB based_on=${yves_company_user_buyer_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M64933
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: Mr Dynamic Customer, Gurmont Str. 23, 8002 Barcelona
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ Yves: shipping address on the order details page is: Mr. Dynamic Customer Spryker Systems GmbH Gurmont Str. 23 8002 Barcelona, Spain 3490284322
+
+Approval_Process
+ [Documentation] Checks role permissions on checkout and Approval process
+ Create dynamic customer in DB based_on=${yves_company_user_buyer_with_limit_email}
+ Create dynamic customer in DB based_on=${yves_company_user_approver_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping Cart' with name: approvalCart+${random}
+ Yves: go to PDP of the product with sku: M49320
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: select approver on the 'Summary' page: Dynamic Customer (€1,000.00)
+ Yves: 'send the request' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: true ${cancelRequestButton} ${alertWarning} ${quoteStatus}
+ Yves: go to shopping cart page
+ Yves: shopping cart contains/doesn't contain the following elements: true ${lockedCart}
+ Yves: create new 'Shopping Cart' with name: newApprovalCart+${random}
+ Yves: go to PDP of the product with sku: M58314
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: newApprovalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: create new 'Shopping Cart' with name: anotherApprovalCart+${random}
+ Yves: go to PDP of the product with sku: M58314
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: anotherApprovalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: select approver on the 'Summary' page: Dynamic Customer (€1,000.00)
+ Yves: 'send the request' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: true ${cancelRequestButton} ${alertWarning} ${quoteStatus}
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: approvalCart+${random} Read-only
+ Yves: the following shopping cart is shown: anotherApprovalCart+${random} Read-only
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Waiting
+ Yves: shopping cart with name xxx has the following status: anotherApprovalCart+${random} Waiting
+ Yves: go to the shopping cart through the header with name: approvalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: 'Summary' page is displayed
+ Yves: 'approve the cart' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: false ${cancelRequestButton} ${alertWarning}
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: approvalCart+${random} Read-only
+ Yves: the following shopping cart is shown: anotherApprovalCart+${random} Read-only
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Approved
+ Yves: shopping cart with name xxx has the following status: anotherApprovalCart+${random} Waiting
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Approved
+ Yves: go to the shopping cart through the header with name: approvalCart+${random}
+ Yves: shopping cart contains/doesn't contain the following elements: true ${lockedCart}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: 'Summary' page is displayed
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Request_for_Quote
+ [Documentation] Checks user can request and receive quote.
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1018212
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: submit new request for quote
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: header contains/doesn't contain: true ${quoteRequestsWidget}
+ Yves: go to 'Agent Quote Requests' page through the header
+ Yves: 'Quote Requests' page is displayed
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Waiting
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page is displayed
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: change price for the product in the quote request with sku xxx on: 403125 500
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: click 'Edit Items' button on the 'Quote Request Details' page
+ Yves: delete product from the shopping cart with sku: 102121
+ Yves: click 'Save and Back to Edit' button on the 'Quote Request Details' page
+ Yves: add the following note to the quote request: Spryker rocks
+ Yves: click 'Save' button on the 'Quote Request Details' page
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: move mouse over header menu item: ${quoteRequestsWidget}
+ Yves: 'Quote Requests' widget is shown
+ Yves: go to the quote request through the header with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page contains the following note: Spryker rocks
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: set 'Valid Till' date for the quote request, today +: 1 day
+ Yves: change price for the product in the quote request with sku xxx on: 403125 500
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Convert to Cart' button on the 'Quote Request Details' page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 500
+ Yves: shopping cart doesn't contain the following products: 102121
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 500
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ [Teardown] Delete dynamic admin user from DB
+
+Unique_URL
+ [Tags] dms-on
+ [Documentation] Bug: https://spryker.atlassian.net/browse/CC-12380
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping Cart' with name: externalCart+${random}
+ Yves: go to PDP of the product with sku: M90806
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: externalCart+${random}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: get link for external cart sharing
+ Yves: logout on Yves as a customer
+ Yves: go to external URL: ${externalURL}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: Shopping Cart title should be equal: Preview: externalCart+${random}
+ Yves: shopping cart contains the following products: 108302
+
+Split_Delivery
+ [Documentation] Checks split delivery in checkout with new addresses
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 403125 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 107254 | Dr. | First | Last | Second Street | 2 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 419904 | Dr. | First | Last | Third Street | 3 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Dr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: click checkout button: Next
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ [Teardown] Delete dynamic admin user from DB
+
+Checkout_Address_Management
+ [Documentation] Bug: CC-30439. Checks that user can change address during the checkout and save new into the address book
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: return to the previous checkout step: Address
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | New | Billing | Changed Street | 098 | 09876 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Shipping Street | 7 | 10247 | Geneva | Switzerland | Spryker | 123456789 | Additional street ||
+ Yves: save new delivery address to address book: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: check that user has address exists/doesn't exist: true First Last Shipping Street 7 10247 Geneva Switzerland
+ Yves: check that user has address exists/doesn't exist: false New Billing Changed Street 098 09876 Berlin Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: billing address for the order should be: New Billing, Changed Street 098, Additional street, 09876 Berlin, Germany 987654321
+ Zed: shipping address inside xxx shipment should be: 1 Mr First, Last, Shipping Street, 7, Additional street, Spryker, 10247, Geneva, Switzerland
+ [Teardown] Delete dynamic admin user from DB
+
+Comments_in_Cart
+ [Documentation] Add comments to cart and verify comments in Yves and Zed
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${bundled_product_3_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: add comment on cart: abc${random}
+ Yves: check comments are visible or not in cart: true abc${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: go to order details page to check comment: abc${random} ${lastPlacedOrder}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: check comment appears at order detailed page in zed: abc${random} ${lastPlacedOrder}
+ [Teardown] Delete dynamic admin user from DB
+
+Comment_Management_in_the_Cart
+ [Documentation] Editing and deleting comments in carts
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${bundled_product_3_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: add comment on cart: abc${random}
+ Yves: check comments are visible or not in cart: true abc${random}
+ Yves: edit comment on cart: xyz${random}
+ Yves: check comments are visible or not in cart: true xyz${random}
+ Yves: delete comment on cart
+ Yves: check comments are visible or not in cart: false xyz${random}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/company/company.robot b/atest/testdata/performance/tests/parallel_ui/b2b/company/company.robot
new file mode 100644
index 0000000..1ff6027
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/company/company.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common_ui.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/company_steps.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+
+*** Test Cases ***
+Create_new_company_with_linked_entities_and_customer_in_backoffice
+ [Documentation] Create a new company with linked entities and new customer in backoffice
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Company with provided name: RobotCompany
+ Zed: click Action Button in a table for row that contains: ${created_company} Activate
+ Zed: click Action Button in a table for row that contains: ${created_company} Approve
+ Zed: create new Company Business Unit for the following company: company_name=${created_company} company_id=${created_company_id} business_unit_name=Robot_Business_Unit
+ Zed: create new Company Role with provided permissions: ${created_company} ${created_company_id} RobotRole true View company users See Company Menu
+ Zed: Create new Company User with provided details:
+ ... || email | salutation | first_name | last_name | gender | company | business_unit | role ||
+ ... || sonia+created+cuser+${random}@spryker.com | Ms | Robot | User | Female | ${created_company}| ${created_business_unit} | RobotRole ||
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: sonia+created+cuser+${random}@spryker.com
+ Yves: go to URL: /company/user
+ ${location}= Get Location
+ Should Contain ${location} /company/user msg=Failed to navigate to the 'Company User' page
+ Yves: go to URL: /company/company-role
+ ${location}= Get Location
+ Should Contain ${location} /403 msg=Navigated to the 'Company Role' page despite the lack of permissions
+ [Teardown] Delete dynamic admin user from DB
+
+Create_new_company_user_with_linked_entities_in_storefront
+ [Documentation] Create a new company user on Storefront
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB based_on=${yves_spryker_admin_company_user_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new company role: RobotYvesRole+${random}
+ Yves: assign the following permissions to the company role: RobotYvesRole+${random} View company users See Company Menu
+ Yves: create new company business unit: business_unit_name=RobotYvesBusinessUnit+${random} business_unit_email=robot+business+unit+${random}@spryker.com
+ Yves: create new company user: business_unit=RobotYvesBusinessUnit+${random} email=sonia+sf+new+cuser+${random}@spryker.com role=RobotYvesRole+${random} first_name=Sonia last_name=NewUser
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: sonia+sf+new+cuser+${random}@spryker.com
+ Yves: go to URL: /company/user
+ ${location}= Get Location
+ Should Contain ${location} /company/user msg=Failed to navigate to the 'Company User' page
+ Yves: go to URL: /company/company-role
+ ${location}= Get Location
+ Should Contain ${location} /403 msg=Navigated to the 'Company Role' page despite the lack of permissions
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/content/content.robot b/atest/testdata/performance/tests/parallel_ui/b2b/content/content.robot
new file mode 100644
index 0000000..38558ff
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/content/content.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Content_Management
+ [Documentation] Checks cms content can be edited in zed and that correct cms elements are present on homepage
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Test Page${random} test-page${random} Page Title Page text
+ Yves: go to the 'Home' page
+ Yves: page contains CMS element: Homepage Banners
+ Yves: page contains CMS element: Product Slider Top Sellers
+ Yves: page contains CMS element: Homepage Inspirational block
+ Yves: page contains CMS element: Footer section
+ Yves: go to newly created page by URL: en/test-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Test Page${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/customers/customer.robot b/atest/testdata/performance/tests/parallel_ui/b2b/customers/customer.robot
new file mode 100644
index 0000000..ab2a534
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/customers/customer.robot
@@ -0,0 +1,200 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/company_steps.robot
+
+*** Test Cases ***
+Guest_User_Access_Restrictions
+ [Documentation] Checks that guest users are not able to see: Prices, Availability, Quick Order, "My Account" features
+ Create dynamic customer in DB
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: header contains/doesn't contain: false ${priceModeSwitcher} ${currencySwitcher}[${env}] ${quickOrderIcon} ${accountIcon} ${shopping_list_icon_header_menu_item}[${env}] ${shoppingCartIcon}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: false ${pdpPriceLocator} ${addToCartButton}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: header contains/doesn't contain: true ${priceModeSwitcher} ${currencySwitcher}[${env}] ${quickOrderIcon} ${accountIcon} ${shopping_list_icon_header_menu_item}[${env}] ${shoppingCartIcon}
+ Yves: company menu 'should' be available for logged in user
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton}
+ Yves: go to company menu item: Users
+ Yves: 'Company Users' page is displayed
+
+Share_Shopping_Lists
+ [Documentation] Checks that shopping list can be shared
+ [Setup] Run Keywords Create dynamic customer in DB based_on=${yves_company_user_shared_permission_owner_email} email=sonia+sharelist${random}@spryker.com first_name=Share${random} last_name=List${random}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_shared_permission_receiver_email} email=sonia+receivelist${random}@spryker.com first_name=Receive${random} last_name=List${random}
+ Yves: login on Yves with provided credentials: sonia+sharelist${random}@spryker.com
+ Yves: go to 'Shopping Lists' page
+ Yves: 'Shopping Lists' page is displayed
+ Yves: create new 'Shopping List' with name: shareShoppingList+${random}
+ Yves: the following shopping list is shown: shoppingListName=shareShoppingList+${random} shoppingListOwner=Share${random} List${random} shoppingListAccess=Full access
+ Yves: share shopping list with user: shoppingListName=shareShoppingList+${random} customer=Receive${random} List${random} accessLevel=Full access
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping list: shareShoppingList+${random}
+ Create New Context
+ Yves: login on Yves with provided credentials: sonia+receivelist${random}@spryker.com
+ Yves: 'Shopping List' widget contains: shareShoppingList+${random} Full access
+ Yves: go to 'Shopping Lists' page
+ Yves: 'Shopping Lists' page is displayed
+ Yves: the following shopping list is shown: shoppingListName=shareShoppingList+${random} shoppingListOwner=Share${random} List${random} shoppingListAccess=Full access
+ Yves: view shopping list with name: shareShoppingList+${random}
+ Yves: add all available products from list to cart
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 403125
+ [Teardown] Run Keywords Close Current Context
+
+Share_Shopping_Carts
+ [Documentation] Checks that cart can be shared and used for checkout
+ [Setup] Run Keywords Create dynamic customer in DB based_on=${yves_company_user_shared_permission_owner_email} email=sonia+sharecart${random}@spryker.com first_name=Share${random} last_name=Cart${random}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_shared_permission_receiver_email} email=sonia+receivecart${random}@spryker.com first_name=Receive${random} last_name=Cart${random}
+ Yves: login on Yves with provided credentials: sonia+sharecart${random}@spryker.com
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: create new 'Shopping Cart' with name: shoppingCartName+${random}
+ Yves: 'Shopping Carts' widget contains: shoppingCartName+${random} Owner access
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: shoppingCartName+${random} Owner access
+ ### Check that cart can be shared with a user with full access ###
+ Yves: share shopping cart with user: shoppingCartName+${random} Cart${random} Receive${random} Full access
+ Yves: go to PDP of the product with sku: M10569
+ Yves: add product to the shopping cart
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: sonia+receivecart${random}@spryker.com
+ Yves: 'Shopping Carts' widget contains: shoppingCartName+${random} Full access
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: shoppingCartName+${random} Full access
+ Yves: go to the shopping cart through the header with name: shoppingCartName+${random}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 100414
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ ### Check that cart can be shared with a user with read-only access ###
+ Yves: login on Yves with provided credentials: sonia+sharecart${random}@spryker.com
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: create new 'Shopping Cart' with name: readShoppingCartName+${random}
+ Yves: 'Shopping Carts' widget contains: readShoppingCartName+${random} Owner access
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: readShoppingCartName+${random} Owner access
+ Yves: share shopping cart with user: readShoppingCartName+${random} Cart${random} Receive${random} Read-only
+ Yves: go to PDP of the product with sku: ${concrete_avaiable_product_sku}
+ Yves: add product to the shopping cart
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: sonia+receivecart${random}@spryker.com
+ Yves: 'Shopping Carts' widget contains: readShoppingCartName+${random} Read-only
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: readShoppingCartName+${random} Read-only
+ Yves: go to the shopping cart through the header with name: readShoppingCartName+${random}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: ${concrete_avaiable_product_sku}
+ Yves: shopping cart contains product with unit price: ${concrete_avaiable_product_sku} ${concrete_avaiable_product_name} ${concrete_avaiable_product_price}
+ Yves: shopping cart contains/doesn't contain the following elements: false ${shopping_cart_checkout_button}
+
+Business_on_Behalf
+ [Documentation] Check that BoB user has possibility to change the business unit
+ Create dynamic customer in DB first_name=Oryx${random} last_name=Bob
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Customers Company Users
+ Zed: click Action Button in a table for row that contains: Oryx${random} Attach to BU
+ Zed: attach company user to the following BU with role: Spryker Systems Zurich Admin
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/company/user/select
+ Yves: 'Select Business Unit' page is displayed
+ Yves: 'Business Unit' dropdown contains: Spryker Systems GmbH / Spryker Systems HR department Spryker Systems GmbH / Spryker Systems Zurich
+ [Teardown] Run Keywords Zed: delete company user xxx withing xxx company business unit: Oryx${random} Spryker Systems Zurich
+ ... AND Delete dynamic admin user from DB
+
+User_Account
+ [Documentation] Checks user account pages work + address management
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: delete all user addresses
+ Yves: go to user menu item in the left bar: Newsletter
+ Yves: 'Newsletter' page is displayed
+ Yves: go to user menu item in the left bar: Returns
+ Yves: 'Returns' page is displayed
+ Yves: create a new customer address in profile: Ms ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: true ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Yves: delete user address: Kirncher Str. ${random}
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: false ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a new customer address in profile:
+ ... || email | salutation | first name | last name | address 1 | address 2 | address 3 | city | zip code | country | phone | company ||
+ ... || ${dynamic_customer} | Ms | ${yves_user_first_name}${random} | ${yves_user_last_name}${random} | address 1${random} | address 2 ${random} | address 3 ${random} | Berlin${random} | ${random} | Austria | 123456789 | Spryker${random} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: check that user has address exists/doesn't exist: true ${yves_user_first_name}${random} ${yves_user_last_name}${random} address 1${random} address 2 ${random} ${random} Berlin${random} Austria
+ [Teardown] Delete dynamic admin user from DB
+
+Update_Customer_Data
+ [Documentation] Checks customer data can be updated from Yves and Zed
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Ms. | Dynamic | Customer | ${dynamic_customer} ||
+ Yves: update customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assert customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Dr | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Zed: update customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Mr | Dynamic${random} | Customer${random} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Mr. | Dynamic${random} | Customer${random} | ${dynamic_customer} ||
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/data_exchange/data_exchange.robot b/atest/testdata/performance/tests/parallel_ui/b2b/data_exchange/data_exchange.robot
new file mode 100644
index 0000000..88e85d6
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/data_exchange/data_exchange.robot
@@ -0,0 +1,121 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/dynamic_entity_steps.robot
+Resource ../../../../resources/steps/api_dynamic_entity_steps.robot
+
+*** Test Cases ***
+Data_exchange_API_download_specification
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: download data exchange api specification should be active: true
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /dynamic-entity/product-abstracts
+ Zed: check that downloaded api specification does not contain: /dynamic-entity/mime-types
+ Zed: delete downloaded api specification
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Zed: download data exchange api specification should be active: false
+ Trigger API specification update
+ Zed: wait until info box is not displayed
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /mime-types
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Zed: delete downloaded api specification
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
+
+Data_exchange_API_Configuration_in_Zed
+ [Tags] bapi
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Trigger API specification update
+ Trigger multistore p&s
+ Zed: wait until info box is not displayed
+ API_test_setup
+ I get access token by user credentials: ${dynamic_admin_user}
+ ### CREATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ I send a POST request: /dynamic-entity/mime-types {"data":[{"name":"POST ${random}","is_allowed":false,"extensions":"fake"}]}
+ Response status code should be: 201
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][0][name] POST ${random}
+ Response body parameter should be: [data][0][is_allowed] False
+ Response body parameter should be: [data][0][extensions] fake
+ Response body parameter should be: [data][0][comment] None
+ Save value to a variable: [data][0][id_mime_type] id_mime_type
+ ### UPDATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I send a PATCH request: /dynamic-entity/mime-types/${id_mime_type} {"data":{"comment":null,"extensions":"dummy","is_allowed":true,"name":"PATCH ${random}"}}
+ Response status code should be: 200
+ ### GET UPDATE TEST MIME TYPE BY ID ###
+ I send a GET request: /dynamic-entity/mime-types/${id_mime_type}
+ Response status code should be: 200
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][name] PATCH ${random}
+ Response body parameter should be: [data][is_allowed] True
+ Response body parameter should be: [data][extensions] dummy
+ Response body parameter should be: [data][comment] None
+ ### DELETE TEST CONFIGURATION AND TEST MIME TYPE FROM DB ###
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Delete mime_type by id_mime_type in Database: ${id_mime_type}
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/marketplace/marketplace.robot b/atest/testdata/performance/tests/parallel_ui/b2b/marketplace/marketplace.robot
new file mode 100644
index 0000000..d62332b
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/marketplace/marketplace.robot
@@ -0,0 +1,19 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+
+*** Test Cases ***
+Default_Merchants
+ Create dynamic admin user in DB
+ [Documentation] Checks that default merchants are present in Zed
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: B2B Contracts Merchants
+ Zed: table should contain: Restrictions Merchant
+ Zed: table should contain: Prices Merchant
+ Zed: table should contain: Products Restrictions Merchant
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/merchandising/merchandising.robot b/atest/testdata/performance/tests/parallel_ui/b2b/merchandising/merchandising.robot
new file mode 100644
index 0000000..7278b6f
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/merchandising/merchandising.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/product_set_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/configurable_bundle_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Product_Sets
+ [Documentation] Checks that product set can be added into cart.
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/product-sets
+ Yves: 'Product Sets' page contains the following sets: The Presenter's Set Basic office supplies The ultimate data disposal set
+ Yves: view the following Product Set: Basic office supplies
+ Yves: 'Product Set' page contains the following products: Clairefontaine Collegeblock 8272C DIN A5, 90 sheets
+ Yves: change variant of the product on CMS page on: Clairefontaine Collegeblock 8272C DIN A5, 90 sheets lined
+ Yves: add all products to the shopping cart from Product Set
+ Yves: shopping cart contains the following products: 421344 420687 421511 423452
+
+Product_Relations
+ [Documentation] Checks related product on PDP and upsell products in cart
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: PDP contains/doesn't contain: true ${relatedProducts}
+ Yves: go to PDP of the product with sku: ${product_with_relations_upselling_sku}
+ Yves: PDP contains/doesn't contain: false ${relatedProducts}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains/doesn't contain the following elements: true ${upSellProducts}
+
+Configurable_Bundle
+ [Documentation] Checks checkout with the configurable bundle
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to second navigation item level: More Configurable Bundle
+ Yves: 'Choose Bundle to configure' page is displayed
+ Yves: choose bundle template to configure: Presentation bundle
+ Yves: select product in the bundle slot: Slot 5 408104
+ Yves: select product in the bundle slot: Slot 6 423172
+ Yves: go to 'Summary' step in the bundle configurator
+ Yves: add products to the shopping cart in the bundle configurator
+ Yves: go to second navigation item level: More Configurable Bundle
+ Yves: 'Choose Bundle to configure' page is displayed
+ Yves: choose bundle template to configure: Presentation bundle
+ Yves: select product in the bundle slot: Slot 5 421539
+ Yves: select product in the bundle slot: Slot 6 424551
+ Yves: go to 'Summary' step in the bundle configurator
+ Yves: add products to the shopping cart in the bundle configurator
+ Yves: change quantity of the configurable bundle in the shopping cart on: Presentation bundle 2
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ Yves: 'Order Details' page contains the following product title N times: Presentation bundle 3
+
+Product_labels
+ [Documentation] Checks that products have labels on PLP and PDP
+ Trigger product labels update
+ Yves: go to first navigation item level: Sale %
+ Yves: 1st product card in catalog (not)contains: Sale label true
+ Yves: go to the PDP of the first product on open catalog page
+ Yves: PDP contains/doesn't contain: true ${pdp_sales_label}[${env}]
+ Yves: go to first navigation item level: New
+ Yves: 1st product card in catalog (not)contains: New label true
+ Yves: go to the PDP of the first product on open catalog page
+ Yves: PDP contains/doesn't contain: true ${pdp_new_label}[${env}]
+
+CRUD_Product_Set
+ [Documentation] CRUD operations for product sets. DMS-ON: https://spryker.atlassian.net/browse/FRW-7393
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new product set:
+ ... || name en | name de | url en | url de | set key | active | product | product 2 | product 3 ||
+ ... || test set ${random} | test set ${random} | test-set-${random} | test-set-${random} | test${random} | true | ${one_variant_product_abstract_sku} | ${multi_color_product_abstract_sku} | ${product_with_relations_related_products_sku} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to newly created page by URL: en/test-set-${random}
+ Yves: 'Product Set' page contains the following products: QUIPO universal steel cabinet with swing doors - HxWxD 1950 x 950 x 420 mm - light gray, from 3 pieces
+ Yves: 'Product Set' page contains the following products: Safescan automatic banknote counter - with 6-fold Counterfeit recognition, EUR value counting, SAFESCAN 2665-S
+ Yves: 'Product Set' page contains the following products: EUROKRAFT hand truck - with open shovel - load capacity 400 kg
+ Yves: add all products to the shopping cart from Product Set
+ Yves: shopping cart contains the following products: 107254 419904 403125
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: delete product set: test set ${random}
+ Trigger multistore p&s
+ Yves: go to URL and refresh until 404 occurs: ${yves_url}en/test-set-${random}
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/misc/static_demodata_set.robot b/atest/testdata/performance/tests/parallel_ui/b2b/misc/static_demodata_set.robot
new file mode 100644
index 0000000..5877dee
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/misc/static_demodata_set.robot
@@ -0,0 +1,104 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure static-set
+Resource ../../../../resources/common/common_ui.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/minimum_order_value_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/zed_discount_steps.robot
+
+*** Test Cases ***
+Minimum_Order_Value
+ [Documentation] checks that global minimum and maximum order thresholds can be applied
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold fixed fee | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | 5 | EN minimum {{threshold}} | DE minimum {{threshold}} | 400 | EN max {{threshold}} | DE max {{threshold}} | Soft Threshold with fixed fee | 100000 | 9 | EN fixed {{fee}} fee | DE fixed {{fee}} fee ||
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: hard threshold is applied with the following message: €400.00
+ Yves: go to shopping cart page
+ Yves: delete product from the shopping cart with sku: 403125
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €227.29
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | ${SPACE} | ${SPACE} | ${SPACE} | 10000.00 | The cart value cannot be higher than {{threshold}}. Please remove some items to proceed with the order | Der Warenkorbwert darf nicht höher als {{threshold}} sein. Bitte entfernen Sie einige Artikel, um mit der Bestellung fortzufahren | None | ${EMPTY} | ${EMPTY} | ${EMPTY} ||
+ ... AND Delete dynamic admin user from DB
+
+Discounts
+ [Documentation] Discounts, Promo Products, and Coupon Codes
+ [Setup] Run keywords Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change product stock: M21777 421538 true 10
+ ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a discount and activate it: voucher Percentage 5 sku = '*' test${random} discountName=Voucher Code 5% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 10 sku = '*' discountName=Cart Rule 10% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 100 discountName=Promotional Product 100% ${random} promotionalProductDiscount=True promotionalProductAbstractSku=M29503 promotionalProductQuantity=2
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M21777
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: apply discount voucher to cart: test${random}
+ Yves: discount is applied: voucher Voucher Code 5% ${random} - €0.72
+ Yves: discount is applied: cart rule Cart Rule 10% ${random} - €1.44
+ Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: discount is applied: cart rule Cart Rule 10% ${random} - €125.46
+ Yves: promotional product offer is/not shown in cart: true
+ Yves: change quantity of promotional product and add to cart: + 1
+ Yves: shopping cart contains the following products: 419873 421538 000101
+ Yves: discount is applied: cart rule Promotional Product 100% ${random} - €123.10
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,072.31
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: Deactivate Following Discounts From Overview Page: Voucher Code 5% ${random} Cart Rule 10% ${random} Promotional Product 100% ${random}
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_catalog.robot b/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_catalog.robot
new file mode 100644
index 0000000..3c12f0d
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_catalog.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+
+*** Test Cases ***
+Multistore_Product
+ [Documentation] check product multistore functionality
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | store 2 | name en | name de | new from | new to ||
+ ... || multiSKU${random} | DE | AT | multiProduct${random} | DEmultiProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 ||
+ ... || farbe | grey ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Standard Taxes ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || AT | gross | default | € | 200.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || multiSKU${random} | multiSKU${random}-farbe-grey | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || multiSKU${random} | multiSKU${random}-farbe-grey | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || multiSKU${random} | multiSKU${random}-farbe-grey | AT | gross | default | € | 25.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || multiSKU${random} | multiSKU${random}-farbe-grey | Warehouse2 | 100 | true ||
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || multiSKU${random} | DEmultiProduct${random} forced ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/search?q=multiSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €100.00
+ Yves: go to PDP of the product with sku: multiSKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: go to AT store 'Home' page if other store not specified:
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to AT store URL if other store not specified: en/search?q=multiSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €200.00
+ Yves: go to PDP of the product with sku: multiSKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €25.00 wait_for_p&s=true
+ Save current URL
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: multiSKU${random}-farbe-grey multiProduct${random} 25.00
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multiSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multiSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Delete dynamic admin user from DB
+
+Multistore_CMS
+ [Documentation] check CMS multistore functionality
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Multistore Page${random} multistore-page${random} Multistore Page Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL on AT store if other store not specified: en/multistore-page${random}
+ Save current URL
+ Yves: page contains CMS element: CMS Page Title Multistore Page
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update cms page and publish it:
+ ... || cmsPage | unselect store ||
+ ... || Multistore Page${random} | AT ||
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Multistore Page${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_dms.robot b/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_dms.robot
new file mode 100644
index 0000000..209bb05
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/multistore/multistore_dms.robot
@@ -0,0 +1,79 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_store_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/zed_cms_block_steps.robot
+
+*** Test Cases ***
+Dynamic_multistore
+ [Documentation] This test should exclusively run for dynamic multi-store scenarios. The test verifies that the user can successfully create a new store, assign a product and CMS page, and register a customer within the new store.
+ [Tags] dms-on
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Store:
+ ... || name | locale_iso_code | currency_iso_code | currency_code | currency_iso_code2 | currency_code2 |store_delivery_region | store_context_timezone ||
+ ... || ${random_str_store}_${random_str_store} | en_US | Euro | EUR | Swiss Franc | CHF | AT | Europe/Berlin ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: wait until store switcher contains: store=${random_str_store}_${random_str_store}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || store | productAbstract ||
+ ... || ${random_str_store}_${random_str_store} | ${one_variant_product_abstract_sku} ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || ${one_variant_product_abstract_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 160.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 15.00 ||
+ Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Warehouse1 | ${random_str_store}_${random_str_store} ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | Warehouse1 | 100 | true ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || ${one_variant_product_abstract_sku} | DEmanageProduct${random} force ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: select currency Euro if other currency not specified
+ Yves: create new 'Shopping Cart' with name: storeCart+${random}
+ Yves: go to PDP of the product with sku: ${one_variant_product_concrete_sku}
+ Yves: product price on the PDP should be: €15.00
+ #### create new cms page and check it in new store on YVES
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: New Page Store${random} store-page${random} Page Title Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Content Page text
+ ## assigned CMS BLocks to new store
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--html
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--text
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: New Page Store${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/sales/manage_shipments.robot b/atest/testdata/performance/tests/parallel_ui/b2b/sales/manage_shipments.robot
new file mode 100644
index 0000000..c1d0366
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/sales/manage_shipments.robot
@@ -0,0 +1,80 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Manage_Shipments
+ [Documentation] Checks create/edit shipment functions from backoffice
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 403125 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 107254 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 419904 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Dr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: click checkout button: Next
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,375.26
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 1
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 1 | Hermes | Next Day | €15.00 | ASAP ||
+ Zed: create new shipment inside the order:
+ ... || delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | sku ||
+ ... || New address | Mr | Evil | Tester | ${dynamic_customer} | Austria | Hartmanngasse | 1 | Vienna | 1050 | DHL - Standard | 419904 ||
+ Zed: billing address for the order should be: First Last, Billing Street 123, Additional street, 10247 Berlin, Germany 987654321
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 2
+ Zed: shipping address inside xxx shipment should be: 1 Dr First, Last, First Street, 1, Additional street, Spryker, 10247, Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 2 Mr Evil, Tester, Hartmanngasse, 1, 1050, Vienna, Austria
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: edit xxx shipment inside the order:
+ ... || shipmentN | delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | requested delivery date | sku ||
+ ... || 2 | New address | Mr | Edit | Shipment | ${dynamic_customer} | Germany | Hartmanngasse | 9 | Vienna | 0987 | DHL - Express | 2025-01-25 | 107254 ||
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 3 | DHL | Express | €0.00 | 2025-01-25 ||
+ Zed: xxx shipment should/not contain the following products: 1 true 403125
+ Zed: xxx shipment should/not contain the following products: 1 false 419904
+ Zed: xxx shipment should/not contain the following products: 2 true 419904
+ Zed: xxx shipment should/not contain the following products: 3 true 107254
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,375.26
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/sales/refunds.robot b/atest/testdata/performance/tests/parallel_ui/b2b/sales/refunds.robot
new file mode 100644
index 0000000..b3dd4f4
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/sales/refunds.robot
@@ -0,0 +1,49 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Refunds
+ [Documentation] Checks that refund can be created for an item and the whole order
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,366.16
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Ship
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Stock
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,162.87
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} Ship
+ Zed: trigger all matching states inside this order: Stock update
+ Zed: trigger all matching states inside this order: Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/sales/sales.robot b/atest/testdata/performance/tests/parallel_ui/b2b/sales/sales.robot
new file mode 100644
index 0000000..2b899be
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/sales/sales.robot
@@ -0,0 +1,185 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+Resource ../../../../resources/steps/order_comments_steps.robot
+
+*** Test Cases ***
+Return_Management
+ [Documentation] Checks OMS and that Yves and Zed users can create returns.
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M90802
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M21711
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M90737
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: Ship
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: Return ${lastPlacedOrder}
+ Yves: 'Create Return' page is displayed
+ Yves: create return for the following products: 410083
+ Yves: 'Return Details' page is displayed
+ Yves: check that 'Print Slip' contains the following products: 410083
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a return for the following order and product in it: ${lastPlacedOrder} 421426
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: go to user menu: Order History
+ Yves: 'View Order/Reorder/Return' on the order history page: Return ${lastPlacedOrder}
+ Yves: 'Create Return' page is displayed
+ Yves: create return for the following products: 108278
+ Yves: 'Return Details' page is displayed
+ Yves: check that 'Print Slip' contains the following products: 108278
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} Execute return
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: 'Order History' page contains the following order with a status: ${lastPlacedOrder} Returned
+ [Teardown] Delete dynamic admin user from DB
+
+Order_Cancellation
+ [Documentation] Check that customer is able to cancel order
+ Create dynamic admin user in DB
+ Create dynamic customer in DB based_on=${yves_company_user_buyer_email}
+ Create dynamic customer in DB based_on=${yves_user_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to 'Order History' page
+ Yves: get the last placed order ID by current customer
+ Yves: cancel the order: ${lastPlacedOrder}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: wait for order item to be in state: 403125 cancelled
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to 'Order History' page
+ Yves: get the last placed order ID by current customer
+ Trigger oms
+ ### change the order state of one product ###
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger matching state of order item inside xxx shipment: 403125 Pay
+ Zed: trigger matching state of order item inside xxx shipment: 403125 Skip timeout
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: false
+ ### change state of state of all products ###
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Pay
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Skip timeout
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: false
+ ### try to cancel order of another customer ###
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to 'Order History' page
+ Yves: get the last placed order ID by current customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: go to 'Order History' page
+ Yves: filter order history by business unit: Company Orders
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: false
+ [Teardown] Delete dynamic admin user from DB
+
+Comment_Management_in_Order
+ [Documentation] Add comments in Yves and check in Zed.
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${bundled_product_3_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: add comment on order in order detail page: abc${random}
+ Yves: check comments is visible or not in order: true abc${random}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: check comment appears at order detailed page in zed: abc${random} ${lastPlacedOrder}
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2b/users/users.robot b/atest/testdata/performance/tests/parallel_ui/b2b/users/users.robot
new file mode 100644
index 0000000..e472d91
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2b/users/users.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_users_steps.robot
+
+*** Test Cases ***
+Agent_Assist
+ [Documentation] Checks Agent creation and that it can login under customer.
+ Create dynamic admin user in DB
+ Create dynamic customer in DB based_on=${yves_company_user_special_prices_customer_email} first_name=DynamicCustomerForAgent${random}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Zed user with the following data: agent+${random}@spryker.com ${default_secure_password} Agent Assist Root group This user is an agent en_US
+ Yves: go to the 'Home' page
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: agent+${random}@spryker.com ${default_secure_password} agent_assist=${True}
+ Yves: header contains/doesn't contain: true ${customerSearchWidget}
+ Yves: perform search by customer: DynamicCustomerForAgent${random}
+ Yves: agent widget contains: ${dynamic_customer}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: perform search by: ${one_variant_product_abstract_name}
+ Yves: product with name in the catalog should have price: ${one_variant_product_abstract_name} ${one_variant_product_merchant_price}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: product price on the PDP should be: ${one_variant_product_merchant_price}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: delete Zed user with the following email: agent+${random}@spryker.com
+
+User_Control
+ [Documentation] Create a user with limited access
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new role with name: controlRole${random}
+ Zed: apply access permissions for user role: ${full_access} ${full_access} ${full_access} ${permission_allow}
+ Zed: apply access permissions for user role: ${bundle_access} ${controller_access} ${action_access} ${permission_deny}
+ Zed: create new group with role assigned: controlGroup${random} controlRole${random}
+ Zed: create new Zed user with the following data: sonia+control${random}@spryker.com ${default_secure_password} First Control Last Control ControlGroup${random} This user is an agent en_US
+ Zed: login on Zed with provided credentials: sonia+control${random}@spryker.com ${default_secure_password}
+ Zed: go to second navigation item level: Catalog Attributes
+ Zed: click button in Header: Create Product Attribute
+ Zed: validate the message when permission is restricted: Access denied
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: deactivate the created user: sonia+control${random}@spryker.com
+ Zed: login with deactivated user/invalid data: sonia+control${random}@spryker.com ${default_secure_password}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Users User Roles
+ ... AND Zed: click Action Button in a table for row that contains: controlRole${random} Delete
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/administration/administration.robot b/atest/testdata/performance/tests/parallel_ui/b2c/administration/administration.robot
new file mode 100644
index 0000000..de49df8
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/administration/administration.robot
@@ -0,0 +1,86 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/zed_root_menus_steps.robot
+Resource ../../../../resources/steps/zed_payment_methods_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/glossary_steps.robot
+
+*** Test Cases ***
+Zed_navigation_ordering_and_naming
+ [Documentation] Verifies each left navigation node can be opened
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: verify first navigation root menus
+ Zed: verify root menu icons
+ Zed: verify second navigation root menus
+ [Teardown] Delete dynamic admin user from DB
+
+Payment_method_update
+ [Documentation] Deactivate payment method, unset payment method for stores in zed and check its impact on yves.
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: activate/deactivate payment method: Dummy Payment Credit Card true
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 020
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: fill in the following new shipping address:
+ ... || firstName | lastName | street | houseNumber | city | postCode | phone ||
+ ... || ${yves_second_user_first_name} | ${yves_second_user_last_name} | ${random} | ${random} | Berlin | ${random} | ${random} ||
+ Yves: billing address same as shipping address: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Standard: €4.90
+ Yves: check that the payment method is/not present in the checkout process: ${checkout_payment_credit_card_locator} true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: activate/deactivate payment method: Dummy Payment Credit Card False
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: fill in the following new shipping address:
+ ... || firstName | lastName | street | houseNumber | city | postCode | phone ||
+ ... || ${yves_second_user_first_name} | ${yves_second_user_last_name} | ${random} | ${random} | Berlin | ${random} | ${random} ||
+ Yves: billing address same as shipping address: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Standard: €4.90
+ Yves: check that the payment method is/not present in the checkout process: ${checkout_payment_credit_card_locator} false
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: activate/deactivate payment method: Dummy Payment Credit Card True
+ ... AND Delete dynamic admin user from DB
+
+Glossary
+ [Documentation] Create + edit glossary translation in BO
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click button in Header: Create Translation
+ Zed: fill glossary form:
+ ... || Name | EN_US | DE_DE ||
+ ... || cart.price.test${random} | This is a sample translation | Dies ist eine Beispielübersetzung ||
+ Zed: submit the form
+ Zed: table should contain: cart.price.test${random}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click Action Button in a table for row that contains: ${glossary_name} Edit
+ Zed: fill glossary form:
+ ... || DE_DE | EN_US ||
+ ... || ${original_DE_text}-Test | ${original_EN_text}-Test-${random} ||
+ Zed: submit the form
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}-Test-${random}
+ Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}
+ [Teardown] Run Keywords Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ ... AND Trigger p&s
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog.robot
new file mode 100644
index 0000000..0ec8c8e
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog.robot
@@ -0,0 +1,194 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+
+*** Test Cases ***
+Catalog
+ [Documentation] Checks that catalog options and search work
+ Trigger multistore p&s
+ Yves: go to the 'Home' page
+ Yves: perform search by: canon
+ Yves: 'Catalog' page should show products: 30
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 2
+ Yves: go to first navigation item level: Computers
+ Yves: 'Catalog' page should show products: 72
+ Yves: page contains CMS element: Product Slider Top Sellers
+ Yves: page contains CMS element: Banner Computers
+ Yves: change sorting order on catalog page: Sort by price ascending
+ Yves: 1st product card in catalog (not)contains: Price €18.79
+ Yves: change sorting order on catalog page: Sort by price descending
+ Yves: 1st product card in catalog (not)contains: Price €3,456.99
+ Yves: go to catalog page: 2
+ Yves: catalog page contains filter: Price Ratings Label Brand Color
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 2
+ [Teardown] Yves: check if cart is not empty and clear it
+
+Catalog_Actions
+ [Documentation] Checks quick add to cart and product groups
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || 003 | 003_26138343 | DE | gross | default| € | 65.00 ||
+ Trigger p&s
+ Yves: check if cart is not empty and clear it
+ Yves: perform search by: NEX-VG20EH
+ Yves: 1st product card in catalog (not)contains: Add to Cart true
+ Yves: quick add to cart for first item in catalog
+ Yves: perform search by: 115_26408656
+ Yves: 1st product card in catalog (not)contains: Add to Cart false
+ Yves: perform search by: 002_25904004
+ Yves: 1st product card in catalog (not)contains: Add to Cart true
+ Yves: 1st product card in catalog (not)contains: Color selector true
+ Yves: mouse over color on product card: silver
+ Yves: quick add to cart for first item in catalog
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: NEX-VG20EH Canon IXUS 160
+ Yves: shopping cart contains product with unit price: 002 Canon IXUS 160 65.00
+ [Teardown] Run Keywords Yves: check if cart is not empty and clear it
+ ... AND Delete dynamic admin user from DB
+
+Product_PDP
+ [Documentation] Checks that PDP contains required elements
+ Create dynamic customer in DB
+ Delete All Cookies
+ Yves: go to PDP of the product with sku: 135
+ Yves: change variant of the product on PDP on: Flash
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton} ${pdp_warranty_option} ${pdp_gift_wrapping_option}[${env}] ${relatedProducts}
+ Yves: PDP contains/doesn't contain: false ${pdp_add_to_wishlist_button}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 135
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${pdp_add_to_cart_disabled_button}[${env}] ${pdp_warranty_option} ${pdp_gift_wrapping_option}[${env}] ${pdp_add_to_wishlist_button} ${relatedProducts}
+ Yves: change variant of the product on PDP on: Flash
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton} ${pdp_warranty_option} ${pdp_gift_wrapping_option}[${env}] ${pdp_add_to_wishlist_button} ${relatedProducts}
+
+Discontinued_Alternative_Products
+ [Documentation] Checks discontinued and alternative products
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: go to PDP of the product with sku: ${product_with_relations_alternative_products_sku}
+ Yves: change variant of the product on PDP on: 2.3 GHz
+ Yves: PDP contains/doesn't contain: true ${alternativeProducts}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${discontinued_product_concrete_sku}
+ Yves: add product to wishlist: My wishlist
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: discontinue the following product: ${discontinued_product_abstract_sku} ${discontinued_product_concrete_sku}
+ Zed: product is successfully discontinued
+ Zed: check if at least one price exists for concrete and add if doesn't: 100
+ Zed: add following alternative products to the concrete: 012
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Wishlist' page
+ Yves: go to wishlist with name: My wishlist
+ Yves: product with sku is marked as discontinued in wishlist: ${discontinued_product_concrete_sku}
+ Yves: product with sku is marked as alternative in wishlist: 012
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: undo discontinue the following product: ${discontinued_product_abstract_sku} ${discontinued_product_concrete_sku}
+ ... AND Trigger p&s
+ ... AND Delete dynamic admin user from DB
+
+Back_in_Stock_Notification
+ [Documentation] Back in stock notification is sent and availability check
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} false 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} false
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} false
+ Yves: submit back in stock notification request for email: ${yves_second_user_email}
+ Yves: unsubscribe from availability notifications
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} true 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} true
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} true
+ [Teardown] Run Keywords Zed: check and restore product availability in Zed: ${stock_product_abstract_sku} Available ${stock_product_concrete_sku} ${dynamic_admin_user}
+ ... AND Delete dynamic admin user from DB
+
+Product_Bundles
+ [Documentation] Checks checkout with Bundle product
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${bundleItemsSmall}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: ${bundle_product_product_name}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ [Teardown] Delete dynamic admin user from DB
+
+Configurable_Product_PDP_Wishlist_Availability
+ [Documentation] Configure product from PDP and Wishlist + availability case.
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Yves: login on Yves with provided credentials: ${dynamic_customer}
+ ... AND Yves: create new 'Wishlist' with name: configProduct${random}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change variant of the product on PDP on: ${configurable_product_concrete_one_attribute}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product price on the PDP should be: €25.00
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: check and go back that configuration page contains:
+ ... || store | locale | price_mode | currency | sku ||
+ ... || DE | en_US | GROSS_MODE | EUR | ${configurable_product_concrete_one_sku} ||
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 517 | 473 | 100 | 0.00 | 51 | 19 | 367 | 46 | 72 | English Keyboard ||
+ Yves: product configuration price should be: €1599.00
+ Yves: save product configuration
+ Yves: product price on the PDP should be: €25.00
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 389.50 | 210 | 36 | 15 | 19 | 48 | 46 | 33 | English Keyboard ||
+ Yves: product configuration price should be: €731.50
+ Yves: product configuration notification is: Only 7 items available
+ Yves: save product configuration
+ Yves: change quantity using '+' or '-' button № times: + 8
+ Yves: try add product to the cart from PDP and expect error: Item ${configurable_product_concrete_one_sku} only has availability of 7.
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change variant of the product on PDP on: ${configurable_product_concrete_one_attribute}
+ Yves: change quantity using '+' or '-' button № times: + 7
+ Yves: add product to wishlist: configProduct${random} select
+ Yves: go to wishlist with name: configProduct${random}
+ Yves: wishlist contains product with sku: ${configurable_product_concrete_one_sku}
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 905 | 249 | 100 | 36 | 15 | 0.00 | 48 | 57 | 36 | German Keyboard ||
+ Yves: product configuration price should be: €1,346.00
+ Yves: save product configuration
+ Yves: add all available products from wishlist to cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_one_sku} productName=${configurable_product_name} productPrice=€1,347.00
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_configurable_product.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_configurable_product.robot
new file mode 100644
index 0000000..30c0237
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_configurable_product.robot
@@ -0,0 +1,122 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+** Test Cases ***
+Configurable_Product_Checkout
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Yves: login on Yves with provided credentials: ${dynamic_customer}
+ ... AND Yves: create new 'Wishlist' with name: configProduct${random}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change variant of the product on PDP on: ${configurable_product_concrete_one_attribute}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 517 | 473 | 100 | 0.00 | 51 | 19 | 367 | 46 | 72 | English Keyboard ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_one_sku} productName=${configurable_product_name} productPrice=1,599.00
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 905 | 249 | 100 | 36 | 15 | 0.00 | 48 | 57 | 36 | German Keyboard ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_one_sku} productName=${configurable_product_name} productPrice=1,346.00
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,361.00
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: skip picking
+ Zed: trigger all matching states inside this order: Ship
+ Zed: trigger all matching states inside this order: Stock update
+ Zed: trigger all matching states inside this order: Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ [Teardown] Delete dynamic admin user from DB
+
+Configurable_Product_OMS
+ [Documentation] Conf Product OMS check and reorder.
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change variant of the product on PDP on: ${configurable_product_concrete_one_attribute}
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 517 | 473 | 100 | 0.00 | 51 | 19 | 367 | 46 | 72 | English Keyboard ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_one_attribute} productName=${configurable_product_name} productPrice=1,599.00
+ Yves: change the product options in configurator to:
+ ... || option one | option two | option three |option four | option five | option six | option seven | option eight | option nine | option ten ||
+ ... || 905 | 249 | 100 | 36 | 15 | 0.00 | 48 | 57 | 36 | German Keyboard ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_one_attribute} productName=${configurable_product_name} productPrice=1,346.00
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Trigger oms
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,361.00
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: skip picking
+ Zed: trigger matching state of xxx order item inside xxx shipment: Ship 1
+ Zed: trigger matching state of xxx order item inside xxx shipment: Stock-update 1
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: 'View Order/Reorder/Return' on the order history page: Return ${lastPlacedOrder}
+ Yves: 'Create Return' page is displayed
+ Yves: create return for the following products: ${configurable_product_concrete_one_sku}
+ Yves: 'Return Details' page is displayed
+ Yves: check that 'Print Slip' contains the following products: ${configurable_product_concrete_one_sku}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} Execute return
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Orders History
+ ### Reorder ###
+ Yves: 'View Order/Reorder/Return' on the order history page: Reorder ${lastPlacedOrder}
+ Yves: go to shopping cart page
+ Yves: product configuration status should be equal: Configuration is not complete.
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_manage_product.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_manage_product.robot
new file mode 100644
index 0000000..1a4ac4b
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_manage_product.robot
@@ -0,0 +1,114 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Manage_Product
+ [Documentation] checks that BO user can manage abstract and concrete products + create new
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | name en | name de | new from | new to ||
+ ... || manageSKU${random} | DE | manageProduct${random} | DEmanageProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 | attribute 2 | attribute value 2 ||
+ ... || color | grey | color | blue ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-color-grey | true | true | true ||
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-color-blue | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | manageSKU${random}-color-blue | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-color-grey | Warehouse1 | 100 | true ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-color-blue | Warehouse1 | 100 | false ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || manageSKU${random} | DEmanageProduct${random} force ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: manageSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change variant of the product on PDP on: grey
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: blue
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: add new concrete product to abstract:
+ ... || productAbstract | sku | autogenerate sku | attribute 1 | name en | name de | use prices from abstract ||
+ ... || manageSKU${random} | manageSKU${random}-color-black | false | black | ENaddedConcrete${random} | DEaddedConcrete${random} | true ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || manageSKU${random} | manageSKU${random}-color-black | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | manageSKU${random}-color-black | DE | gross | default | € | 25.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || manageSKU${random} | manageSKU${random}-color-black | Warehouse1 | 5 | false ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || manageSKU${random} | DE | gross | default | € | 150.00 | Smart Electronics ||
+ Zed: save abstract product: manageSKU${random}
+ Trigger multistore p&s
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || manageSKU${random} | DE | gross | default | € | 150.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name en | name de ||
+ ... || manageSKU${random} | ENUpdatedmanageProduct${random} | DEUpdatedmanageProduct${random} ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: check if cart is not empty and clear it
+ Yves: go to PDP of the product with sku: manageSKU${random} wait_for_p&s=true
+ Yves: product name on PDP should be: ENUpdatedmanageProduct${random}
+ Yves: product price on the PDP should be: €150.00 wait_for_p&s=true
+ Yves: change variant of the product on PDP on: grey
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: blue
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: black
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product name on PDP should be: ENaddedConcrete${random}
+ Yves: product price on the PDP should be: €25.00 wait_for_p&s=true
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item manageSKU${random}-color-black only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: manageSKU${random}-color-black ENaddedConcrete${random} 75.00
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: manageProduct${random} View
+ Zed: view product page is displayed
+ Zed: view abstract product page contains:
+ ... || store | sku | name | variants count ||
+ ... || DE AT | manageSKU${random} | ENUpdatedmanageProduct${random} | 3 ||
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_prices.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_prices.robot
new file mode 100644
index 0000000..35e2176
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_prices.robot
@@ -0,0 +1,68 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Product_Original_Price
+ [Documentation] checks that Original price is displayed on the PDP and in Catalog
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | name en | name de | new from | new to ||
+ ... || originalSKU${random} | DE | originalProduct${random} | DEoriginalProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 | attribute 2 | attribute value 2 ||
+ ... || color | grey | color | blue ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Smart Electronics ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | original | € | 200.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || originalSKU${random} | originalSKU${random}-color-grey | true | true | true ||
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || originalSKU${random} | originalSKU${random}-color-blue | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || originalSKU${random} | originalSKU${random}-color-blue | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || originalSKU${random} | originalSKU${random}-color-blue | DE | gross | original | € | 50.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || originalSKU${random} | originalSKU${random}-color-grey | Warehouse1 | 100 | true ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || originalSKU${random} | originalSKU${random}-color-blue | Warehouse1 | 100 | false ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || originalSKU${random} | originalSKU${random} forced ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/search?q=originalSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €100.00
+ Yves: 1st product card in catalog (not)contains: Original Price €200.00
+ Yves: go to PDP of the product with sku: originalSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: product original price on the PDP should be: €200.00
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change variant of the product on PDP on: blue
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: product original price on the PDP should be: €50.00
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_product_availability.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_product_availability.robot
new file mode 100644
index 0000000..71e06b1
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_product_availability.robot
@@ -0,0 +1,111 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+
+*** Test Cases ***
+Product_Availability_Calculation
+ [Documentation] Check product availability + multistore. DMS-ON: https://spryker.atlassian.net/browse/FRW-7477
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Warehouse1 | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: start new abstract product creation:
+ ... || sku | store | store 2 | name en | name de | new from | new to ||
+ ... || availabilitySKU${random} | DE | AT | availabilityProduct${random} | DEavailabilityProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 ||
+ ... || color | grey ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Smart Electronics ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || AT | gross | default | € | 200.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-color-grey | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-color-grey | DE | gross | default | € | 50.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-color-grey | AT | gross | default | € | 75.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || availabilitySKU${random} | availabilitySKU${random}-color-grey | Warehouse1 | 5 | false ||
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || availabilitySKU${random} | DEavailabilityProduct${random} force ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-color-grey only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: wait for order item to be in state: sku=availabilitySKU${random}-color-grey state=payment pending iterations=7
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-color-grey only has availability of 2.
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: Cancel
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-color-grey only has availability of 5.
+ Yves: go to AT store 'Home' page if other store not specified:
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update warehouse:
+ ... || warehouse | unselect store ||
+ ... || Warehouse1 | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to AT store 'Home' page if other store not specified:
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: update warehouse:
+ ... || warehouse | unselect store ||
+ ... || Warehouse1 | AT ||
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_volume_prices.robot b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_volume_prices.robot
new file mode 100644
index 0000000..9f50096
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/catalog/catalog_volume_prices.robot
@@ -0,0 +1,25 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Volume_Prices
+ [Documentation] Checks volume prices are applied
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 193
+ Yves: change quantity using '+' or '-' button № times: + 4
+ Yves: product price on the PDP should be: €165.00
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 193 Sony FDR-AX40 825.00
+ Yves: delete from b2c cart products with name: Sony FDR-AX40
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout.robot b/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout.robot
new file mode 100644
index 0000000..cba4471
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout.robot
@@ -0,0 +1,149 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/zed_customer_steps.robot
+
+*** Test Cases ***
+Split_Delivery
+ [Documentation] Checks split delivery in checkout and check dashboard graph created in zed.
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 005
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 012
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 285 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 175 | Dr. | First | Last | Second Street | 2 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 165 | Dr. | First | Last | Third Street | 3 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ [Teardown] Delete dynamic admin user from DB
+
+Checkout_Address_Management
+ [Documentation] Bug: CC-30439. Checks that user can change address during the checkout and save new into the address book
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: return to the previous checkout step: Address
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | New | Billing | Changed Street | 098 | 09876 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Shipping Street | 7 | 10247 | Geneva | Switzerland | Spryker | 123456789 | Additional street ||
+ Yves: save new delivery address to address book: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: check that user has address exists/doesn't exist: true First Last Shipping Street 7 10247 Geneva Switzerland
+ Yves: check that user has address exists/doesn't exist: false New Billing Changed Street 098 09876 Berlin Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: billing address for the order should be: New Billing, Changed Street 098, 09876 Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 1 Mr First, Last, Shipping Street, 7, Additional street, Spryker, 10247, Geneva, Switzerland
+ [Teardown] Delete dynamic admin user from DB
+
+Login_during_checkout
+ Create dynamic customer in DB
+ Yves: go to the 'Home' page
+ Yves: go to PDP of the product with sku: ${bundled_product_3_concrete_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: proceed as a guest user and login during checkout: ${dynamic_customer}
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || ${Salutation} | ${Guest_user_first_name} | ${Guest_user_last_name} | ${random} | ${random} | ${random} | ${city} | ${country} | ${company} | ${random} | ${additional_address} ||
+ Yves: billing address same as shipping address: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+
+Register_during_checkout
+ [Documentation] Guest user email should be whitelisted from the AWS side before running the test
+ [Tags] glue
+ [Setup] Create dynamic admin user in DB
+ Yves: go to the 'Home' page
+ Yves: go to PDP of the product with sku: ${bundled_product_3_concrete_sku}
+ Yves: add product to the shopping cart
+ Page Should Not Contain Element ${pdp_add_to_wishlist_button}
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: signup guest user during checkout: ${guest_user_first_name} ${guest_user_last_name} sonia+guest${random}@spryker.com ${default_secure_password} ${default_secure_password}
+ Save the result of a SELECT DB query to a variable: select registration_key from spy_customer where email = 'sonia+guest${random}@spryker.com' confirmation_key
+ API_test_setup
+ I send a POST request: /customer-confirmation {"data":{"type":"customer-confirmation","attributes":{"registrationKey":"${confirmation_key}"}}}
+ Yves: login after signup during checkout: sonia+guest${random}@spryker.com ${default_secure_password}
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || ${salutation} | ${guest_user_first_name} | ${guest_user_last_name} | ${random} | ${random} | ${random} | ${city} | ${country} | ${company} | ${random} | ${additional_address} ||
+ Yves: billing address same as shipping address: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: My Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || ${salutation} | ${guest_user_first_name} | ${guest_user_last_name} | sonia+guest${random}@spryker.com ||
+ [Teardown] Zed: delete customer: sonia+guest${random}@spryker.com
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout_guest.robot b/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout_guest.robot
new file mode 100644
index 0000000..be235ec
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/checkout/checkout_guest.robot
@@ -0,0 +1,100 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Guest_Checkout
+ [Documentation] Guest checkout with bundles, discounts and OMS.
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+ ... AND Deactivate all discounts in the database
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${bundleItemsSmall}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 008
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: apply discount voucher to cart: guestTest${random}
+ Yves: shopping cart contains the following products: ${bundle_product_product_name}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: proceed with checkout as guest: Mr Guest user sonia+guest+checkout${random}@spryker.com
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | Guest | User | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: get the last placed order ID of the customer by email: sonia+guest+checkout${random}@spryker.com
+ Zed: trigger all matching states inside xxx order: ${zedLastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ [Teardown] Run keywords Yves: check if cart is not empty and clear it
+ ... AND Delete dynamic admin user from DB
+
+Guest_Checkout_Addresses
+ [Documentation] Guest checkout with different addresses and OMS.
+ [Setup] Create dynamic admin user in DB
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 005
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 012
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: proceed with checkout as guest: Mr Guest user sonia+guest+new${random}@spryker.com
+ Yves: billing address same as shipping address: true
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 285 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 175 | Dr. | First | Last | Second Street | 2 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 165 | Dr. | First | Last | Third Street | 3 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: get the last placed order ID of the customer by email: sonia+guest+new${random}@spryker.com
+ Zed: go to order page: ${zedLastPlacedOrder}
+ Zed: billing address for the order should be: First Last, Billing Street 123, 10247 Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 1 Dr First, Last, First Street, 1, Additional street, Spryker, 10247, Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 2 Dr First, Last, Second Street, 2, Additional street, Spryker, 10247, Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 3 Dr First, Last, Third Street, 3, Additional street, Spryker, 10247, Berlin, Germany
+ [Teardown] Run keywords Yves: check if cart is not empty and clear it
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/content/content.robot b/atest/testdata/performance/tests/parallel_ui/b2c/content/content.robot
new file mode 100644
index 0000000..4d85600
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/content/content.robot
@@ -0,0 +1,29 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Content_Management
+ [Documentation] Checks cms content can be edited in zed and that correct cms elements are present on homepage
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Test Page${random} test-page${random} Page Title Page text
+ Yves: go to the 'Home' page
+ Yves: page contains CMS element: Homepage Banners
+ Yves: page contains CMS element: Product Slider Top Sellers
+ Yves: page contains CMS element: Homepage Inspirational block
+ Yves: page contains CMS element: Homepage Banner Video
+ Yves: page contains CMS element: Footer section
+ Yves: go to newly created page by URL: en/test-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Test Page${random} Deactivate
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/customers/customer.robot b/atest/testdata/performance/tests/parallel_ui/b2c/customers/customer.robot
new file mode 100644
index 0000000..3774cbf
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/customers/customer.robot
@@ -0,0 +1,179 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/customer_registration_steps.robot
+Resource ../../../../resources/steps/zed_customer_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+New_Customer_Registration
+ [Documentation] Check that a new user can be registered in the system
+ Create dynamic admin user in DB
+ Register a new customer with data:
+ ... || salutation | first name | last name | e-mail | password ||
+ ... || Mr. | New | User | sonia+ui+new${random}@spryker.com | ${default_secure_password} ||
+ Yves: flash message should be shown: success Almost there! We send you an email to validate your email address. Please confirm it to be able to log in.
+ [Teardown] Run Keywords Zed: delete customer: sonia+ui+new${random}@spryker.com
+ ... AND Delete dynamic admin user from DB
+
+Guest_User_Access_Restrictions
+ [Documentation] Checks that guest users see products info and cart but not profile
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: header contains/doesn't contain: true ${currencySwitcher}[${env}] ${wishlistIcon} ${accountIcon} ${shoppingCartIcon}
+ Yves: go to PDP of the product with sku: 002
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 002 Canon IXUS 160 37.50
+ Yves: go to user menu: Overview
+ Yves: 'Login' page is displayed
+ Yves: go to 'Wishlist' page
+ Yves: 'Login' page is displayed
+
+Authorized_User_Access
+ [Documentation] Checks that authorized users see products info, cart and profile
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: header contains/doesn't contain: true ${currencySwitcher}[${env}] ${accountIcon} ${wishlistIcon} ${shoppingCartIcon}
+ Yves: go to PDP of the product with sku: 002
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 002 Canon IXUS 160 37.50
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: go to 'Wishlist' page
+ Yves: 'Wishlist' page is displayed
+
+User_Account
+ [Documentation] Checks user account pages work + address management
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: go to user menu: My Profile
+ Yves: 'Profile' page is displayed
+ Yves: go to 'Wishlist' page
+ Yves: 'Wishlist' page is displayed
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: go to user menu item in the left bar: Newsletter
+ Yves: 'Newsletter' page is displayed
+ Yves: go to user menu item in the left bar: Returns
+ Yves: 'Returns' page is displayed
+ Yves: create a new customer address in profile: Mr ${yves_second_user_first_name} ${random} ${yves_second_user_last_name} ${random} Kirncher Str. ${random} 7 10247 Berlin${random} Germany
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: true ${yves_second_user_first_name} ${random} ${yves_second_user_last_name} ${random} Kirncher Str. ${random} 7 10247 Berlin${random} Germany
+ Yves: delete user address: Kirncher Str. ${random}
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: false ${yves_second_user_first_name} ${random} ${yves_second_user_last_name} ${random} Kirncher Str. ${random} 7 10247 Berlin${random} Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a new customer address in profile:
+ ... || email | salutation | first name | last name | address 1 | address 2 | address 3 | city | zip code | country | phone | company ||
+ ... || ${dynamic_customer} | Mr | ${yves_second_user_first_name}${random} | ${yves_second_user_last_name}${random} | address 1${random} | address 2 ${random} | address 3 ${random} | Berlin${random} | ${random} | Austria | 123456789 | Spryker${random} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: check that user has address exists/doesn't exist: true ${yves_second_user_first_name}${random} ${yves_second_user_last_name}${random} address 1${random} address 2 ${random} ${random} Berlin${random} Austria
+ [Teardown] Delete dynamic admin user from DB
+
+Add_to_Wishlist
+ [Documentation] Check creation of wishlist and adding to different wishlists
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 003
+ Yves: add product to wishlist: My wishlist
+ Yves: go to 'Wishlist' page
+ Yves: create wishlist with name: Second wishlist
+ Yves: go to PDP of the product with sku: 004
+ Yves: add product to wishlist: Second wishlist select
+ Yves: go to 'Wishlist' page
+ Yves: go to wishlist with name: My wishlist
+ Yves: wishlist contains product with sku: 003_26138343
+ Yves: go to wishlist with name: Second wishlist
+ Yves: wishlist contains product with sku: 004_30663302
+ Yves: go to PDP of the product with sku: ${bundled_product_3_concrete_sku}
+ Delete All Cookies
+ Yves: try to add product to wishlist as guest user
+
+Reorder
+ [Documentation] Checks that merchant relation is saved with reorder
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: Canon IXUS 285
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | Guest | User | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: Reorder ${lastPlacedOrder}
+ Yves: shopping cart contains the following products: Canon IXUS 285
+
+Update_Customer_Data
+ [Documentation] Checks customer data can be updated from Yves and Zed
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: My Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Ms. | Dynamic | Customer | ${dynamic_customer} ||
+ Yves: update customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_second_user_first_name} | updated${yves_second_user_last_name} ||
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_second_user_first_name} | updated${yves_second_user_last_name} ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assert customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Dr | updated${yves_second_user_first_name} | updated${yves_second_user_last_name} ||
+ Zed: update customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Mr | ${yves_second_user_first_name} | ${yves_second_user_last_name} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: My Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | ${dynamic_customer} ||
+ [Teardown] Delete dynamic admin user from DB
+
+Email_Confirmation
+ [Documentation] Check that a new user cannot login if the email is not verified
+ Register a new customer with data:
+ ... || salutation | first name | last name | e-mail | password ||
+ ... || Mr. | New | User | sonia+ui+fails+${random}@spryker.com | ${default_secure_password} ||
+ Yves: flash message should be shown: success Almost there! We send you an email to validate your email address. Please confirm it to be able to log in.
+ Yves: login on Yves with provided credentials and expect error: sonia+ui+fails+${random}@spryker.com ${default_secure_password}
+ [Teardown] Run Keywords Create dynamic admin user in DB
+ ... AND Zed: delete customer: sonia+ui+fails+${random}@spryker.com
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/data_exchange/data_exchange.robot b/atest/testdata/performance/tests/parallel_ui/b2c/data_exchange/data_exchange.robot
new file mode 100644
index 0000000..88e85d6
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/data_exchange/data_exchange.robot
@@ -0,0 +1,121 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/dynamic_entity_steps.robot
+Resource ../../../../resources/steps/api_dynamic_entity_steps.robot
+
+*** Test Cases ***
+Data_exchange_API_download_specification
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: download data exchange api specification should be active: true
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /dynamic-entity/product-abstracts
+ Zed: check that downloaded api specification does not contain: /dynamic-entity/mime-types
+ Zed: delete downloaded api specification
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Zed: download data exchange api specification should be active: false
+ Trigger API specification update
+ Zed: wait until info box is not displayed
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /mime-types
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Zed: delete downloaded api specification
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
+
+Data_exchange_API_Configuration_in_Zed
+ [Tags] bapi
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Trigger API specification update
+ Trigger multistore p&s
+ Zed: wait until info box is not displayed
+ API_test_setup
+ I get access token by user credentials: ${dynamic_admin_user}
+ ### CREATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ I send a POST request: /dynamic-entity/mime-types {"data":[{"name":"POST ${random}","is_allowed":false,"extensions":"fake"}]}
+ Response status code should be: 201
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][0][name] POST ${random}
+ Response body parameter should be: [data][0][is_allowed] False
+ Response body parameter should be: [data][0][extensions] fake
+ Response body parameter should be: [data][0][comment] None
+ Save value to a variable: [data][0][id_mime_type] id_mime_type
+ ### UPDATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I send a PATCH request: /dynamic-entity/mime-types/${id_mime_type} {"data":{"comment":null,"extensions":"dummy","is_allowed":true,"name":"PATCH ${random}"}}
+ Response status code should be: 200
+ ### GET UPDATE TEST MIME TYPE BY ID ###
+ I send a GET request: /dynamic-entity/mime-types/${id_mime_type}
+ Response status code should be: 200
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][name] PATCH ${random}
+ Response body parameter should be: [data][is_allowed] True
+ Response body parameter should be: [data][extensions] dummy
+ Response body parameter should be: [data][comment] None
+ ### DELETE TEST CONFIGURATION AND TEST MIME TYPE FROM DB ###
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Delete mime_type by id_mime_type in Database: ${id_mime_type}
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/merchandising/merchandising.robot b/atest/testdata/performance/tests/parallel_ui/b2c/merchandising/merchandising.robot
new file mode 100644
index 0000000..07dd79e
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/merchandising/merchandising.robot
@@ -0,0 +1,124 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/product_set_steps.robot
+Resource ../../../../resources/steps/configurable_bundle_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Product_labels
+ [Documentation] Checks that products have labels on PLP and PDP
+ Trigger product labels update
+ Yves: go to first navigation item level: Sale
+ Yves: 1st product card in catalog (not)contains: Sale label true
+ Yves: go to the PDP of the first product on open catalog page
+ Yves: PDP contains/doesn't contain: true ${pdp_sales_label}[${env}]
+ Yves: go to first navigation item level: New
+ Yves: 1st product card in catalog (not)contains: New label true
+ Yves: go to PDP of the product with sku: 666
+ Yves: PDP contains/doesn't contain: true ${pdp_new_label}[${env}]
+ [Teardown] Yves: check if cart is not empty and clear it
+
+Product_Sets
+ [Documentation] Check the usage of product sets.
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/product-sets
+ Yves: 'Product Sets' page contains the following sets: HP Product Set Sony Product Set Upgrade your running game
+ Yves: view the following Product Set: Upgrade your running game
+ Yves: 'Product Set' page contains the following products: TomTom Golf Samsung Galaxy S6 edge
+ Yves: change variant of the product on CMS page on: Samsung Galaxy S6 edge 128 GB
+ Yves: add all products to the shopping cart from Product Set
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: TomTom Golf Samsung Galaxy S6 edge
+ Yves: delete from b2c cart products with name: TomTom Golf Samsung Galaxy S6 edge
+
+Configurable_Bundle
+ [Documentation] Check the usage of configurable bundles (includes authorized checkout). DMS-ON: https://spryker.atlassian.net/browse/FRW-7463
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/configurable-bundle/configurator/template-selection
+ Yves: 'Choose Bundle to configure' page is displayed
+ Yves: choose bundle template to configure: Smartstation Kit
+ Yves: select product in the bundle slot: Slot 5 Sony Cyber-shot DSC-W830
+ Yves: select product in the bundle slot: Slot 6 Sony NEX-VG30E
+ Yves: go to 'Summary' step in the bundle configurator
+ Yves: add products to the shopping cart in the bundle configurator
+ Yves: go to URL: en/configurable-bundle/configurator/template-selection
+ Yves: 'Choose Bundle to configure' page is displayed
+ Yves: choose bundle template to configure: Smartstation Kit
+ Yves: select product in the bundle slot: Slot 5 Canon IXUS 165
+ Yves: select product in the bundle slot: Slot 6 Sony HDR-MV1
+ Yves: go to 'Summary' step in the bundle configurator
+ Yves: add products to the shopping cart in the bundle configurator
+ Yves: go to shopping cart page
+ Yves: change quantity of the configurable bundle in the shopping cart on: Smartstation Kit 2
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ Yves: 'Order Details' page contains the following product title N times: Smartstation Kit 3
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: skip picking
+ Zed: trigger all matching states inside this order: Ship
+ Zed: trigger all matching states inside this order: Stock update
+ Zed: trigger all matching states inside this order: Close
+
+Product_Relations
+ [Documentation] Checks related product on PDP and upsell products in cart
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: PDP contains/doesn't contain: true ${relatedProducts}
+ Yves: go to PDP of the product with sku: ${product_with_relations_upselling_sku}
+ Yves: PDP contains/doesn't contain: false ${relatedProducts}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains/doesn't contain the following elements: true ${upSellProducts}
+
+CRUD_Product_Set
+ [Documentation] CRUD operations for product sets.
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new product set:
+ ... || name en | name de | url en | url de | set key | active | product | product 2 | product 3 ||
+ ... || test set ${random} | test set ${random} | test-set-${random} | test-set-${random} | test${random} | true | 005 | 007 | 010 ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to newly created page by URL: en/test-set-${random}
+ Yves: 'Product Set' page contains the following products: Canon IXUS 175
+ Yves: 'Product Set' page contains the following products: Canon IXUS 285
+ Yves: 'Product Set' page contains the following products: Canon IXUS 180
+ Yves: add all products to the shopping cart from Product Set
+ Yves: shopping cart contains the following products: Canon IXUS 175
+ Yves: shopping cart contains the following products: Canon IXUS 285
+ Yves: shopping cart contains the following products: Canon IXUS 180
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: delete product set: test set ${random}
+ Trigger multistore p&s
+ Yves: go to URL and refresh until 404 occurs: ${yves_url}en/test-set-${random}
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/misc/static_demodata_set.robot b/atest/testdata/performance/tests/parallel_ui/b2c/misc/static_demodata_set.robot
new file mode 100644
index 0000000..7070311
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/misc/static_demodata_set.robot
@@ -0,0 +1,198 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure static-set
+Resource ../../../../resources/common/common_ui.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/minimum_order_value_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/warehouse_user_assignment_steps.robot
+Resource ../../../../resources/steps/zed_users_steps.robot
+Resource ../../../../resources/steps/picking_list_steps.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/zed_discount_steps.robot
+
+*** Test Cases ***
+Minimum_Order_Value
+ [Documentation] checks that global minimum and maximum order thresholds can be applied
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold fixed fee | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | 5 | EN minimum {{threshold}} | DE minimum {{threshold}} | 150 | EN max {{threshold}} | DE max {{threshold}} | Soft Threshold with fixed fee | 100000 | 9 | EN fixed {{fee}} fee | DE fixed {{fee}} fee ||
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 005
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: hard threshold is applied with the following message: €150.00
+ Yves: go to the 'Home' page
+ Yves: go to shopping cart page
+ Yves: delete product from the shopping cart with name: Canon IXUS 175
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €153.38
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | ${SPACE} | ${SPACE} | ${SPACE} | 10000.00 | The cart value cannot be higher than {{threshold}}. Please remove some items to proceed with the order | Der Warenkorbwert darf nicht höher als {{threshold}} sein. Bitte entfernen Sie einige Artikel, um mit der Bestellung fortzufahren | None | ${EMPTY} | ${EMPTY} | ${EMPTY} ||
+ ... AND Delete dynamic admin user from DB
+
+Fulfillment_app_e2e
+ # # LOGGED IN TO BO and SET CHECKBOX is a warehouse user = true FOR admin_de USER. UI TEST
+ Remove all warehouse user assignments by user uuid: ${warehouse_user[0].de_admin_user_uuid}
+ Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+ Zed: login on Zed with provided credentials: ${zed_admin_email}
+ Zed: update Zed user:
+ ... || oldEmail | user_is_warehouse_user ||
+ ... || admin_de@spryker.com | true ||
+ Remove Tags *
+ Set Tags bapi
+ API_test_setup
+ # # ASSIGN admin_de user TO WAREHOUSE [Warehouse 1] MAKE WAREHOUSE ACTIVE BY BAPI
+ And I get access token by user credentials: ${zed_admin_email}
+ I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ I send a POST request: /warehouse-user-assignments {"data": {"type": "warehouse-user-assignments", "attributes":{"userUuid": "${warehouse_user[0].de_admin_user_uuid}","warehouse" :{"uuid": "${warehouse[0].warehouse_uuid_warehouse1}"},"isActive":"true"}}}
+ Then Response status code should be: 201
+ Then Save value to a variable: [data][id] warehouse_assignment_id
+ # CREATE AN ORDER BY GLUE
+ I set Headers: Content-Type=${default_header_content_type}
+ Remove Tags *
+ Set Tags glue
+ API_test_setup
+ When I get access token for the customer: ${yves_user_email}
+ Then I set Headers: Authorization=${token}
+ When Find or create customer cart
+ Then Cleanup all items in the cart: ${cart_id}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "091_25873091","quantity": 1}}}
+ I send a POST request: /carts/${cart_id}/items?include=items {"data": {"type": "items","attributes": {"sku": "093_24495843","quantity": 1}}}
+ I send a POST request: /checkout-data {"data": {"type": "checkout-data","attributes": {"customer": {"email": "${yves_user_email}","salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"shippingAddress": {"salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": true,"isDefaultShipping": true},"payments": [{"paymentProviderName": "${payment_provider_name_1}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["091_25873091","093_24495843"]}}}
+ Then Response status code should be: 200
+ I send a POST request: /checkout?include=orders {"data": {"type": "checkout","attributes": {"customer": {"email": "${yves_user_email}","salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}"},"idCart": "${cart_id}","billingAddress": {"salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"shippingAddress": {"salutation": "${yves_user_salutation}","firstName": "${yves_user_first_name}","lastName": "${yves_user_last_name}","address1": "${default.address1}","address2": "${default.address2}","address3": "${default.address3}","zipCode": "${default.zipCode}","city": "${default.city}","iso2Code": "${default.iso2Code}","company": "${default.company}","phone": "${default.phone}","isDefaultBilling": false,"isDefaultShipping": false},"payments": [{"paymentProviderName": "${payment_provider_name_1}","paymentMethodName": "${payment_method_name}"}],"shipment": {"idShipmentMethod": 1},"items": ["091_25873091","093_24495843"]}}}
+ Then Response status code should be: 201
+ And Save value to a variable: [included][0][attributes][items][0][uuid] uuid
+ And Save value to a variable: [included][0][attributes][items][1][uuid] uuid1
+ # # MOVE ORDER ITEMS INTO WAITING STATE
+ UI_test_setup
+ Yves: login on Yves with provided credentials: ${yves_user_email}
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${zed_admin_email}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Trigger oms
+ And Update order status in Database: waiting ${uuid}
+ And Update order status in Database: waiting ${uuid1}
+ # # MOVE ORDER ITEMS TO PROPER STATE USING BO, PICKING LIST GENERATED AUTOMATICALLY. UI TEST
+ Trigger oms
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: picking list generation schedule
+ Trigger oms
+ # # ORDER READY FOR PICKING
+ Zed: wait for order item to be in state: 091_25873091 ready for picking
+ Zed: wait for order item to be in state: 093_24495843 ready for picking
+ # # START PICKING PROCESS AND PICKING ITEMS BY BAPI
+ Remove Tags glue
+ Set Tags bapi
+ API_test_setup
+ I set Headers: Content-Type=${default_header_content_type}
+ Then I get access token by user credentials: ${zed_admin_email_de}
+ I set Headers: Content-Type=${default_header_content_type} Authorization=Bearer ${token}
+ I send a GET request: /picking-lists/?include=picking-list-items,concrete-products,sales-shipments,sales-orders,include=warehouses
+ Then Response status code should be: 200
+ Then Save value to a variable: [data][0][id] picklist_id
+ Then Save value to a variable: [data][0][relationships][picking-list-items][data][0][id] item_id_1
+ Then Save value to a variable: [data][0][relationships][picking-list-items][data][1][id] item_id_2
+ And Response body parameter should be: [data][0][attributes][status] ready-for-picking
+ # # START PICKING
+ I send a POST request: /picking-lists/${picklist_id}/start-picking {"data": [{"type": "picking-lists","attributes": {"action": "startPicking"}}]}
+ Then Response status code should be: 201
+ And Response body parameter should be: [data][attributes][status] picking-started
+ # # PICKING ONE ITEM, ANOTHER ITEM STILL NOT PICKED
+ Then I send a PATCH request: /picking-lists/${picklist_id}/picking-list-items {"data":[{"id":"${item_id_1}","type":"picking-list-items","attributes":{"numberOfPicked":1,"numberOfNotPicked":0}},{"id":"${item_id_2}","type":"picking-list-items","attributes":{"numberOfPicked":0,"numberOfNotPicked":0}}]}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][status] picking-started
+ And Response body parameter should be in: [data][0][relationships][picking-list-items][data][0][id] ${item_id_1} ${item_id_2}
+ And Response body parameter should be in: [data][0][relationships][picking-list-items][data][1][id] ${item_id_1} ${item_id_2}
+ # # PICKING SECOND ITEM, PICKING FINISHED
+ Then I send a PATCH request: /picking-lists/${picklist_id}/picking-list-items {"data":[{"id":"${item_id_1}","type":"picking-list-items","attributes":{"numberOfPicked":1,"numberOfNotPicked":0}},{"id":"${item_id_2}","type":"picking-list-items","attributes":{"numberOfPicked":0,"numberOfNotPicked":1}}]}
+ Then Response status code should be: 200
+ And Response body parameter should be: [data][0][attributes][status] picking-finished
+ # CLEAN SYSTEM, REMOVE CREATED RELATIONS IN DB
+ [Teardown] Run Keywords Remove picking list item by uuid in DB: ${item_id_1}
+ ... AND Remove picking list item by uuid in DB: ${item_id_2}
+ ... AND Remove picking list by uuid in DB: ${picklist_id}
+ ... AND Make user a warehouse user/ not a warehouse user: ${warehouse_user[0].de_admin_user_uuid} 0
+ ... AND I send a DELETE request: /warehouse-user-assignments/${warehouse_assignment_id}
+
+Discounts
+ [Documentation] Discounts, Promo Products, and Coupon Codes (includes guest checkout)
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Deactivate all discounts in the database
+ ... AND Zed: change product stock: 190 190_25111746 true 10
+ ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+ ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a discount and activate it: voucher Percentage 5 sku = '*' test${random} discountName=Voucher Code 5% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 10 sku = '*' discountName=Cart Rule 10% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 100 discountName=Promotional Product 100% ${random} promotionalProductDiscount=True promotionalProductAbstractSku=002 promotionalProductQuantity=2
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 190
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: apply discount voucher to cart: test${random}
+ Yves: discount is applied: voucher Voucher Code 5% ${random} - €8.73
+ Yves: discount is applied: cart rule Cart Rule 10% ${random} - €17.46
+ Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: discount is applied: cart rule Cart Rule 10% ${random} - €87.96
+ Yves: promotional product offer is/not shown in cart: true
+ Yves: change quantity of promotional product and add to cart: + 1
+ Yves: shopping cart contains the following products: Kodak EasyShare M532 Canon IXUS 160
+ Yves: discount is applied: cart rule Promotional Product 100% ${random} - €75.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €753.55
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: deactivate following discounts from Overview page: Voucher Code 5% ${random} Cart Rule 10% ${random} Promotional Product 100% ${random}
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_catalog.robot b/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_catalog.robot
new file mode 100644
index 0000000..b1164cd
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_catalog.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+
+*** Test Cases ***
+Multistore_Product
+ [Documentation] check product multistore functionality
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start new abstract product creation:
+ ... || sku | store | store 2 | name en | name de | new from | new to ||
+ ... || multiSKU${random} | DE | AT | multiProduct${random} | DEmultiProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: select abstract product variants:
+ ... || attribute 1 | attribute value 1 ||
+ ... || color | grey ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || DE | gross | default | € | 100.00 | Smart Electronics ||
+ Zed: update abstract product price on:
+ ... || store | mode | type | currency | amount | tax set ||
+ ... || AT | gross | default | € | 200.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || multiSKU${random} | multiSKU${random}-color-grey | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || multiSKU${random} | multiSKU${random}-color-grey | DE | gross | default | € | 15.00 ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || multiSKU${random} | multiSKU${random}-color-grey | AT | gross | default | € | 25.00 ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || multiSKU${random} | multiSKU${random}-color-grey | Warehouse2 | 100 | true ||
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || multiSKU${random} | DEmultiProduct${random} forced ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/search?q=multiSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €100.00
+ Yves: go to PDP of the product with sku: multiSKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ Yves: go to AT store 'Home' page if other store not specified:
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: check if cart is not empty and clear it
+ Yves: go to AT store URL if other store not specified: en/search?q=multiSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €200.00
+ Yves: go to PDP of the product with sku: multiSKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: product price on the PDP should be: €25.00 wait_for_p&s=true
+ Save current URL
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: multiSKU${random}-color-grey multiProduct${random} 25.00
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multiSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multiSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Delete dynamic admin user from DB
+
+Multistore_CMS
+ [Documentation] check CMS multistore functionality
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Multistore Page${random} multistore-page${random} Multistore Page Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL on AT store if other store not specified: en/multistore-page${random}
+ Save current URL
+ Yves: page contains CMS element: CMS Page Title Multistore Page
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update cms page and publish it:
+ ... || cmsPage | unselect store ||
+ ... || Multistore Page${random} | AT ||
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Multistore Page${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_dms.robot b/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_dms.robot
new file mode 100644
index 0000000..43649e1
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/multistore/multistore_dms.robot
@@ -0,0 +1,87 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_store_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/zed_cms_block_steps.robot
+Resource ../../../../resources/steps/customer_registration_steps.robot
+Resource ../../../../resources/steps/zed_customer_steps.robot
+
+*** Test Cases ***
+Dynamic_multistore
+ [Documentation] This test should exclusively run for dynamic multi-store scenarios. The test verifies that the user can successfully create a new store, assign a product and CMS page, and register a customer within the new store.
+ [Tags] dms-on
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Store:
+ ... || name | locale_iso_code | currency_iso_code | currency_code | currency_iso_code2 | currency_code2 | store_delivery_region | store_context_timezone ||
+ ... || ${random_str_store}_${random_str_store} | en_US | Euro | EUR | Swiss Franc | CHF | AT | Europe/Berlin ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: wait until store switcher contains: store=${random_str_store}_${random_str_store}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || store | productAbstract ||
+ ... || ${random_str_store}_${random_str_store} | ${one_variant_product_abstract_sku} ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || ${one_variant_product_abstract_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 160.00 | Smart Electronics ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 15.00 ||
+ Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Warehouse1 | ${random_str_store}_${random_str_store} ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | Warehouse1 | 100 | true ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || ${one_variant_product_abstract_sku} | DEmanageProduct${random} force ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: select currency Euro if other currency not specified
+ Yves: go to PDP of the product with sku: ${one_variant_product_concrete_sku}
+ Yves: product price on the PDP should be: €15.00
+ ### create new cms page and check it in new store on YVES
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: New Page Store${random} store-page${random} Page Title Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Content Page text
+ ## assigned CMS BLocks to new store
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--html
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--text
+ ## register new customer in the new store on YVES
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Register a new customer with data:
+ ... || salutation | first name | last name | e-mail | password ||
+ ... || Mr. | New | User | sonia+ui+dms${random}@spryker.com | ${default_secure_password} ||
+ Yves: flash message should be shown: success Almost there! We send you an email to validate your email address. Please confirm it to be able to log in.
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: New Page Store${random} Deactivate
+ ... AND Zed: delete customer: sonia+ui+dms${random}@spryker.com
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/sales/manage_shipments.robot b/atest/testdata/performance/tests/parallel_ui/b2c/sales/manage_shipments.robot
new file mode 100644
index 0000000..d4c97b2
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/sales/manage_shipments.robot
@@ -0,0 +1,80 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Manage_Shipments
+ [Documentation] Checks create/edit shipment functions from backoffice
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 005
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 012
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 285 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 175 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Canon IXUS 165 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €307.88
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 1
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 1 | Hermes | Next Day | €15.00 | ASAP ||
+ Zed: create new shipment inside the order:
+ ... || delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | sku ||
+ ... || New address | Mr | Evil | Tester | ${dynamic_customer} | Austria | Hartmanngasse | 1 | Vienna | 1050 | DHL - Standard | 012_25904598 ||
+ Zed: billing address for the order should be: First Last, Billing Street 123, 10247 Berlin, Germany
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 2
+ Zed: shipping address inside xxx shipment should be: 1 Dr First, Last, First Street, 1, Additional street, Spryker, 10247, Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 2 Mr Evil, Tester, Hartmanngasse, 1, 1050, Vienna, Austria
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: edit xxx shipment inside the order:
+ ... || shipmentN | delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | requested delivery date | sku ||
+ ... || 2 | New address | Mr | Edit | Shipment | ${dynamic_customer} | Germany | Hartmanngasse | 9 | Vienna | 0987 | DHL - Express | 2025-01-25 | 005_30663301 ||
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 3 | DHL | Express | €0.00 | 2025-01-25 ||
+ Zed: xxx shipment should/not contain the following products: 1 true 007_30691822
+ Zed: xxx shipment should/not contain the following products: 1 false 012_25904598
+ Zed: xxx shipment should/not contain the following products: 2 true 012_25904598
+ Zed: xxx shipment should/not contain the following products: 3 true 005_30663301
+ Zed: grand total for the order equals: ${lastPlacedOrder} €307.88
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/sales/refunds.robot b/atest/testdata/performance/tests/parallel_ui/b2c/sales/refunds.robot
new file mode 100644
index 0000000..7949f9b
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/sales/refunds.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+*** Test Cases ***
+Refunds
+ [Documentation] Checks that refund can be created for one item and the whole order. DMS-ON: https://spryker.atlassian.net/browse/FRW-7463
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 008
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 010
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €394.41
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: skip picking
+ Zed: trigger matching state of order item inside xxx shipment: 008_30692992 Ship
+ Zed: trigger matching state of order item inside xxx shipment: 008_30692992 Stock
+ Zed: trigger matching state of order item inside xxx shipment: 008_30692992 Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €265.03
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} Ship
+ Zed: trigger all matching states inside this order: Stock update
+ Zed: trigger all matching states inside this order: Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/sales/sales.robot b/atest/testdata/performance/tests/parallel_ui/b2c/sales/sales.robot
new file mode 100644
index 0000000..bd54599
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/sales/sales.robot
@@ -0,0 +1,141 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+
+*** Test Cases ***
+Return_Management
+ [Documentation] Checks that returns work and oms process is checked. DMS-ON: https://spryker.atlassian.net/browse/FRW-7463
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: check if cart is not empty and clear it
+ Yves: go to PDP of the product with sku: 007
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 008
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 010
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | Guest | User | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: trigger all matching states inside this order: Skip timeout
+ Zed: trigger all matching states inside this order: skip picking
+ Zed: trigger all matching states inside this order: Ship
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: Return ${lastPlacedOrder}
+ Yves: 'Create Return' page is displayed
+ Yves: create return for the following products: 010_30692994
+ Yves: 'Return Details' page is displayed
+ Yves: check that 'Print Slip' contains the following products: 010_30692994
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: go to user menu: Orders History
+ Yves: 'View Order/Reorder/Return' on the order history page: Return ${lastPlacedOrder}
+ Yves: 'Create Return' page is displayed
+ Yves: create return for the following products: 008_30692992
+ Yves: 'Return Details' page is displayed
+ Yves: check that 'Print Slip' contains the following products: 008_30692992
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} Execute return
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Orders History
+ Yves: 'Order History' page is displayed
+ Yves: 'Order History' page contains the following order with a status: ${lastPlacedOrder} Returned
+ [Teardown] Delete dynamic admin user from DB
+
+Order_Cancellation
+ [Documentation] Check that customer is able to cancel order.
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: check if cart is not empty and clear it
+ Yves: delete all user addresses
+ Yves: go to PDP of the product with sku: 005
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to 'Order History' page
+ Yves: get the last placed order ID by current customer
+ Yves: cancel the order: ${lastPlacedOrder}
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: wait for order item to be in state: 005_30663301 cancelled
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 005_30663301
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 007_30691822
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | ${yves_second_user_first_name} | ${yves_second_user_last_name} | Kirncher Str. | 7 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: go to 'Order History' page
+ Yves: get the last placed order ID by current customer
+ ### change the order state of one product ###
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger matching state of order item inside xxx shipment: 005_30663301 Pay
+ Zed: trigger matching state of order item inside xxx shipment: 005_30663301 Skip timeout
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: false
+ ### change state for all products ###
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger matching state of order item inside xxx shipment: 007_30691822 Pay
+ Zed: trigger matching state of order item inside xxx shipment: 007_30691822 Skip timeout
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Order History' page
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page contains the cancel order button: false
+ [Teardown] Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/b2c/users/users.robot b/atest/testdata/performance/tests/parallel_ui/b2c/users/users.robot
new file mode 100644
index 0000000..8c53b8a
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/b2c/users/users.robot
@@ -0,0 +1,75 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_users_steps.robot
+
+*** Test Cases ***
+Agent_Assist
+ [Documentation] Checks that agent can be used.
+ Create dynamic admin user in DB
+ Create dynamic customer in DB based_on=${yves_second_user_email} first_name=DynamicCustomerForAgent${random} last_name=DynamicCustomerForAgentLast${random}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Zed user with the following data: agent+${random}@spryker.com ${default_secure_password} Agent Assist Root group This user is an agent en_US
+ Yves: go to the 'Home' page
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: agent+${random}@spryker.com ${default_secure_password} agent_assist=${True}
+ Yves: header contains/doesn't contain: true ${customerSearchWidget}
+ Yves: perform search by customer: DynamicCustomerForAgent${random}
+ Yves: agent widget contains: ${dynamic_customer}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: end customer assistance
+ Yves: perform search by customer: DynamicCustomerForAgentLast${random}
+ Yves: agent widget contains: ${dynamic_customer}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: end customer assistance
+ Yves: perform search by customer: ${dynamic_customer}
+ Yves: agent widget contains: ${dynamic_customer}
+ Yves: as an agent login under the customer: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 020
+ Yves: product price on the PDP should be: €105.80
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: fill in the following new shipping address:
+ ... || firstName | lastName | street | houseNumber | city | postCode | phone ||
+ ... || ${yves_second_user_first_name} | ${yves_second_user_last_name} | ${random} | ${random} | Berlin${random} | ${random} | ${random} ||
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Standard: €4.90
+ Yves: select the following payment method on the checkout and go next: Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: get the last placed order ID by current customer
+ Yves: end customer assistance
+ Yves: logout as an agent
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to 'Order History' page
+ Yves: 'Order History' page contains the following order: ${lastPlacedOrder}
+ [Teardown] Delete dynamic admin user from DB
+
+User_Control
+ [Documentation] Create a user with limited access
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new role with name: controlRole${random}
+ Zed: apply access permissions for user role: ${full_access} ${full_access} ${full_access} ${permission_allow}
+ Zed: apply access permissions for user role: ${bundle_access} ${controller_access} ${action_access} ${permission_deny}
+ Zed: create new group with role assigned: controlGroup${random} controlRole${random}
+ Zed: create new Zed user with the following data: sonia+control${random}@spryker.com ${default_secure_password} First Control Last Control ControlGroup${random} This user is an agent en_US
+ Zed: login on Zed with provided credentials: sonia+control${random}@spryker.com ${default_secure_password}
+ Zed: go to second navigation item level: Catalog Attributes
+ Zed: click button in Header: Create Product Attribute
+ Zed: validate the message when permission is restricted: Access denied
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: deactivate the created user: sonia+control${random}@spryker.com
+ Zed: login with deactivated user/invalid data: sonia+control${random}@spryker.com ${default_secure_password}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Users User Roles
+ ... AND Zed: click Action Button in a table for row that contains: controlRole${random} Delete
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/administration/administration.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/administration/administration.robot
new file mode 100644
index 0000000..a77810e
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/administration/administration.robot
@@ -0,0 +1,49 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_root_menus_steps.robot
+Resource ../../../../resources/steps/glossary_steps.robot
+
+*** Test Cases ***
+Zed_navigation_ordering_and_naming
+ [Documentation] Verifies each left navigation node can be opened
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: verify first navigation root menus
+ Zed: verify root menu icons
+ Zed: verify second navigation root menus
+ [Teardown] Delete dynamic admin user from DB
+
+Glossary
+ [Documentation] Create + edit glossary translation in BO
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click button in Header: Create Translation
+ Zed: fill glossary form:
+ ... || Name | EN_US | DE_DE ||
+ ... || cart.price.test${random} | This is a sample translation | Dies ist eine Beispielübersetzung ||
+ Zed: submit the form
+ Zed: table should contain: cart.price.test${random}
+ Zed: go to second navigation item level: Administration Glossary
+ Zed: click Action Button in a table for row that contains: ${glossary_name} Edit
+ Zed: fill glossary form:
+ ... || DE_DE | EN_US ||
+ ... || ${original_DE_text}-Test | ${original_EN_text}-Test-${random} ||
+ Zed: submit the form
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}-Test-${random}
+ Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: validate the page title: ${original_EN_text}
+ [Teardown] Run Keywords Zed: undo the changes in glossary translation: ${glossary_name} ${original_DE_text} ${original_EN_text}
+ ... AND Trigger p&s
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog.robot
new file mode 100644
index 0000000..911929c
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog.robot
@@ -0,0 +1,334 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+
+*** Test Cases ***
+Quick_Order
+ [Documentation] Checks Quick Order, checkout and Reorder
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ ... AND Zed: check and restore product availability in Zed: ${product_with_multiple_offers_abstract_sku} Available ${product_with_multiple_offers_concrete_sku} ${dynamic_admin_user}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping List' with name: quickOrderList+${random}
+ Yves: go to 'Quick Order' page through the header
+ Yves: 'Quick Order' page is displayed
+ Yves: add the following articles into the form through quick order text area: 213103,1\n520561,3\n421340,21\n419871,1\n419869,11\n425073,1\n425084,2
+ Yves: find and add new item in the quick order form:
+ ... || searchQuery | merchant ||
+ ... || ${product_with_multiple_offers_concrete_sku} | Computer Experts ||
+ Yves: add products to the shopping cart from quick order page
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 213103 520561 421340 419871 419869 425073 425084
+ Yves: assert merchant of product in cart or list: 213103 Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: go to 'Quick Order' page through the header
+ Yves: add the following articles into the form through quick order text area: 213103,1\n520561,3\n421340,21\n419871,1\n419869,11\n425073,1\n425084,2
+ Yves: find and add new item in the quick order form:
+ ... || searchQuery | merchant ||
+ ... || ${product_with_multiple_offers_concrete_sku} | Computer Experts ||
+ Yves: add products to the shopping list from quick order page with name: quickOrderList+${random}
+ Yves: 'Shopping List' page is displayed
+ Yves: shopping list contains the following products: 213103 520561 421340 419871 419869 425073 425084
+ Yves: assert merchant of product in cart or list: 213103 Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: go to shopping cart page
+ ### Order placement ###
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 DHL Express
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ ### Order History ###
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ ### Reorder ###
+ Yves: reorder all items from 'Order Details' page
+ Yves: go to the shopping cart through the header with name: Reorder from Order ${lastPlacedOrder}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 213103 520561 421340 419871 419869 425073 425084
+ Yves: assert merchant of product in cart or list: 213103 Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ [Teardown] Delete dynamic admin user from DB
+
+Volume_Prices
+ [Documentation] Checks that volume prices are applied in cart
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: check and restore product availability in Zed: ${volume_prices_product_abstract_sku} Available ${volume_prices_product_concrete_sku} ${dynamic_admin_user}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${volume_prices_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity on PDP: 5
+ Yves: product price on the PDP should be: €4.20
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 420685 Post-it stick note Super Sticky Meeting Notes 6445-4SS 4 pieces/pack 4.20
+ [Teardown] Delete dynamic admin user from DB
+
+Discontinued_Alternative_Products
+ [Documentation] Checks that product can be discontinued in Zed
+ [Setup] Create dynamic admin user in DB
+ Yves: go to PDP of the product with sku: M21100
+ Yves: PDP contains/doesn't contain: true ${alternativeProducts}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: discontinue the following product: ${discontinued_product_abstract_sku} ${discontinued_product_concrete_sku}
+ Zed: product is successfully discontinued
+ Zed: add following alternative products to the concrete: M22613
+ Zed: submit the form
+ [Teardown] Run Keywords Zed: undo discontinue the following product: ${discontinued_product_abstract_sku} ${discontinued_product_concrete_sku}
+ ... AND Delete dynamic admin user from DB
+
+Measurement_Units
+ [Documentation] Checks checkout with Measurement Unit product
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M23723
+ Yves: select the following 'Sales Unit' on PDP: Meter
+ Yves: change quantity using '+' or '-' button № times: + 1
+ Yves: PDP contains/doesn't contain: true ${measurementUnitSuggestion}
+ Yves: change quantity using '+' or '-' button № times: - 1
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1006871
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains the following products: 425079
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Packaging_Units
+ [Documentation] Checks checkout with Packaging Unit product
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M21766
+ Yves: change variant of the product on PDP on: Box
+ Yves: change amount on PDP: 51
+ Yves: PDP contains/doesn't contain: true ${packagingUnitSuggestion}
+ Yves: change amount on PDP: 10
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1006871
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains the following products: 421519_3
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Product_Restrictions
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_restriction_customer_email_1}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_restriction_customer_email_2}
+ [Documentation] Checks White and Black lists
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: Soennecken
+ Yves: 'Catalog' page should show products: 18
+ Yves: go to URL: en/office-furniture/storage/lockers
+ Yves: 'Catalog' page should show products: 34
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: perform search by: Soennecken
+ Yves: 'Catalog' page should show products: 0
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_third_customer}
+ Yves: go to URL: en/office-furniture/storage/lockers
+ Yves: 'Catalog' page should show products: 0
+ Yves: go to URL: en/transport/lift-carts
+ Yves: 'Catalog' page should show products: 16
+ Yves: go to URL: en/transport/sack-trucks
+ Yves: 'Catalog' page should show products: 10
+
+Customer_Specific_Prices
+ [Documentation] Checks that product price can be different for different customers
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_special_prices_customer_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: ${one_variant_product_abstract_name}
+ Yves: product with name in the catalog should have price: ${one_variant_product_abstract_name} ${one_variant_product_default_price}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: product price on the PDP should be: ${one_variant_product_default_price}
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: perform search by: ${one_variant_product_abstract_name}
+ Yves: product with name in the catalog should have price: ${one_variant_product_abstract_name} ${one_variant_product_merchant_price}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: product price on the PDP should be: ${one_variant_product_merchant_price}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 188.34
+
+Product_PDP
+ [Documentation] Checks that PDP contains required elements
+ [Setup] Create dynamic customer in DB
+ Delete All Cookies
+ Yves: go to PDP of the product with sku: ${multi_variant_product_abstract_sku}
+ Yves: change variant of the product on PDP on: 500 x 930 x 400
+ Yves: PDP contains/doesn't contain: true ${pdp_limited_warranty_option}[${env}] ${pdp_insurance_coverage_option}
+ Yves: PDP contains/doesn't contain: false ${pdpPriceLocator} ${addToCartButton}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${multi_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${pdp_add_to_cart_disabled_button}[${env}] ${pdp_limited_warranty_option}[${env}] ${pdp_insurance_coverage_option}
+ Yves: change variant of the product on PDP on: 500 x 930 x 400
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton} ${pdp_limited_warranty_option}[${env}] ${pdp_insurance_coverage_option}
+
+Catalog
+ [Documentation] Checks that catalog options and search work
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Trigger product labels update
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: claire
+ Yves: 'Catalog' page should show products: 15
+ Yves: catalog page contains filter: Product Ratings Product Labels Brand Color Merchant
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 1
+ Yves: go to first navigation item level: Stationery
+ Yves: 'Catalog' page should show products: 114
+ Yves: select filter value: Merchant Spryker
+ Yves: page contains CMS element: CMS Block Build a Space That Spurs Creativity
+ Yves: page contains CMS element: CMS Block Tackle Your To-Do's
+ Yves: change sorting order on catalog page: Sort by price ascending
+ Yves: 1st product card in catalog (not)contains: Price 0.48
+ Yves: change sorting order on catalog page: Sort by price descending
+ Yves: 1st product card in catalog (not)contains: Price €41.68
+ Yves: go to catalog page: 2
+ Yves: catalog page contains filter: Product Ratings Product Labels Brand Color
+ Yves: select filter value: Color blue
+ Yves: 'Catalog' page should show products: 3
+
+Back_in_Stock_Notification
+ [Documentation] Back in stock notification is sent and availability check
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} false 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} false
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} false
+ Yves: submit back in stock notification request for email: ${dynamic_customer}
+ Yves: unsubscribe from availability notifications
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change product stock: ${stock_product_abstract_sku} ${stock_product_concrete_sku} true 0
+ Zed: check if product is/not in stock: ${stock_product_abstract_sku} true
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${stock_product_abstract_sku}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: check if product is available on PDP: ${stock_product_abstract_sku} true
+ [Teardown] Run keywords Zed: check and restore product availability in Zed: ${stock_product_abstract_sku} Available ${stock_product_concrete_sku} ${dynamic_admin_user}
+ ... AND Delete dynamic admin user from DB
+
+Configurable_Product_PDP_Shopping_List
+ [Documentation] Configure products from both the PDP and the Shopping List. Verify the availability of 7 items. Ensure that products that have not been configured cannot be purchased.
+ [Setup] Run keywords Create dynamic customer in DB
+ ... AND Yves: login on Yves with provided credentials: ${dynamic_customer}
+ ... AND Yves: create new 'Shopping List' with name: configProduct+${random}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: checkout is blocked with the following message: This cart can't be processed. Please configure items inside the cart.
+ Yves: delete product from the shopping cart with sku: ${configurable_product_concrete_sku}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: check and go back that configuration page contains:
+ ... || store | locale | price_mode | currency | customer_id | sku ||
+ ... || DE | en_US | GROSS_MODE | EUR | ${yves_company_user_buyer_reference} | ${configurable_product_concrete_sku} ||
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 240 ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 480 ||
+ Yves: product configuration notification is: Only 7 items available
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 5 shelves | 3 lockers ||
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: change quantity on PDP: 8
+ Yves: try add product to the cart from PDP and expect error: Item ${configurable_product_concrete_sku} only has availability of 7.
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change quantity on PDP: 7
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 140 | 240 ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: ${configurable_product_concrete_sku} ${configurable_product_name} €2,206.54
+ Yves: delete all shopping carts
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: add product to the shopping list: configProduct+${random}
+ Yves: go to 'Shopping Lists' page
+ Yves: view shopping list with name: configProduct+${random}
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 240 ||
+ Yves: save product configuration
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 6 shelves | 2 lockers ||
+ Yves: add all available products from list to cart
+ Yves: configuration should be equal:
+ ... || option one | option two ||
+ ... || 6 shelves | 2 lockers ||
+ Yves: shopping cart contains product with unit price: ${configurable_product_concrete_sku} ${configurable_product_name} €2,486.54
+
+#### Product Bundles feature is not present in marketplace for now ####
+# Product_Bundles
+# [Tags] skip-due-to-refactoring
+# [Documentation] Checks checkout with Bundle product
+# [Setup] Run keywords Zed: login on Zed with provided credentials: ${zed_admin_email}
+# ... AND Zed: change product stock: ${bundled_product_1_abstract_sku} ${bundled_product_1_concrete_sku} true 10
+# ... AND Zed: change product stock: ${bundled_product_2_abstract_sku} ${bundled_product_2_concrete_sku} true 10
+# ... AND Zed: change product stock: ${bundled_product_3_abstract_sku} ${bundled_product_3_concrete_sku} true 10
+# Yves: login on Yves with provided credentials: ${yves_company_user_buyer_email}
+# Yves: create new 'Shopping Cart' with name: productBundleCart+${random}
+# Yves: go to PDP of the product with sku: ${bundle_product_abstract_sku}
+# Yves: PDP contains/doesn't contain: true ${bundleItemsSmall}
+# Yves: add product to the shopping cart
+# Yves: go to the shopping cart through the header with name: productBundleCart+${random}
+# Yves: shopping cart contains the following products: ${bundle_product_concrete_sku}
+# Yves: click on the 'Checkout' button in the shopping cart
+# Yves: billing address same as shipping address: true
+# Yves: select the following existing address on the checkout as 'shipping' address and go next: ${yves_company_user_buyer_address}
+# Yves: select the following shipping method on the checkout and go next: Express
+# Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+# Yves: accept the terms and conditions: true
+# Yves: 'submit the order' on the summary page
+# Yves: 'Thank you' page is displayed
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_configurable_product.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_configurable_product.robot
new file mode 100644
index 0000000..bc1e5f3
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_configurable_product.robot
@@ -0,0 +1,119 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/steps/configurable_product_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Configurable_Product_RfQ_OMS
+ [Documentation] Conf Product in RfQ, OMS, Merchant OMS and reorder.
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 480 ||
+ Yves: save product configuration
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: submit new request for quote
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: go to 'Agent Quote Requests' page through the header
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Waiting
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page is displayed
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: click 'Edit Items' button on the 'Quote Request Details' page
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 240 ||
+ Yves: save product configuration
+ Yves: click 'Save and Back to Edit' button on the 'Quote Request Details' page
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Convert to Cart' button on the 'Quote Request Details' page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_merchant}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state of xxx merchant's shipment: 1 send to distribution
+ Zed: trigger matching state of xxx merchant's shipment: 1 confirm at center
+ Zed: trigger matching state of xxx order item inside xxx shipment: Ship 1
+ Zed: trigger matching state of xxx order item inside xxx shipment: Deliver 1
+ Zed: trigger matching state of xxx order item inside xxx shipment: Refund 1
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Order History
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order
+ Yves: 'Order Details' page is displayed
+ ### Reorder ###
+ Yves: reorder all items from 'Order Details' page
+ Yves: go to the shopping cart through the header with name: Reorder from Order ${lastPlacedOrder}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: product configuration status should be equal: Configuration is not complete.
+ [Teardown] Delete dynamic admin user from DB
+
+Configurable_Product_Checkout
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${configurable_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${configureButton}
+ Yves: product configuration status should be equal: Configuration is not complete.
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 280 | 480 ||
+ Yves: save product configuration
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_sku} productName=${configurable_product_name} productPrice=2,586.54
+ Yves: change the product options in configurator to:
+ ... || option one | option two ||
+ ... || 420 | 240 ||
+ Yves: save product configuration
+ Yves: shopping cart contains product with unit price: sku=${configurable_product_concrete_sku} productName=${configurable_product_name} productPrice=2,486.54
+ Yves: product configuration status should be equal: Configuration complete!
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_merchant}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €2,492.44
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_offer_availability.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_offer_availability.robot
new file mode 100644
index 0000000..5e947aa
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_offer_availability.robot
@@ -0,0 +1,127 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Offer_Availability_Calculation
+ [Documentation] check offer availability
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Zed: create dynamic merchant user: Spryker
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ ... AND Repeat Keyword 3 Trigger multistore p&s
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || offAvKU${random} | offAvProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: offAvProduct${random}
+ MP: click on a table row that contains: offAvProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | store 2 | tax set ||
+ ... || offAvProduct${random} | DE | AT | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 1 | DE | EUR | 100 | 90 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 2 | AT | EUR | 200 | 90 ||
+ MP: save abstract product
+ MP: click on a table row that contains: offAvProduct${random}
+ MP: open concrete drawer by SKU: offAvKU${random}-1
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 5 | true | en_US ||
+ MP: open concrete drawer by SKU: offAvKU${random}-1
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 50 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 2 | AT | EUR | 50 ||
+ MP: save concrete product
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: offAvProduct${random} Approve
+ Zed: save abstract product: offAvProduct${random}
+ Trigger multistore p&s
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: offAvKU${random}-1
+ MP: click on a table row that contains: offAvKU${random}-1
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | offAvMKU${random} | DE | 5 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | CHF | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 2 | DE | EUR | 200 | 1 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 3 | AT | EUR | 10 | 1 ||
+ MP: save offer
+ Repeat Keyword 2 Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: offAvKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker true
+ Yves: merchant's offer/product price should be: Spryker €200.00
+ Yves: select xxx merchant's offer: Spryker
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item offAvKU${random}-1 only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: offAvKU${random}-1 Spryker
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Yves: go to PDP of the product with sku: offAvKU${random}
+ Yves: select xxx merchant's offer: Spryker
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item offAvKU${random}-1 only has availability of 2.
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_second_merchant}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state of xxx merchant's shipment: 1 Cancel
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: offAvKU${random}
+ Yves: select xxx merchant's offer: Spryker
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item offAvKU${random}-1 only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: offAvKU${random}-1 Spryker
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: offAvProduct${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_product_availability.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_product_availability.robot
new file mode 100644
index 0000000..05a6834
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/catalog/catalog_product_availability.robot
@@ -0,0 +1,118 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/availability_steps.robot
+
+*** Test Cases ***
+Product_Availability_Calculation
+ [Documentation] Check product availability + multistore
+ [Setup] Run Keywords Repeat Keyword 3 Trigger multistore p&s
+ ... AND Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Spryker
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || availabilitySKU${random} | availabilityProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: availabilityProduct${random}
+ MP: click on a table row that contains: availabilityProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | store 2 | tax set ||
+ ... || availabilityProduct${random} | DE | AT | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 1 | DE | EUR | 100 | 90 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 2 | AT | EUR | 200 | 90 ||
+ MP: save abstract product
+ Trigger multistore p&s
+ MP: click on a table row that contains: availabilityProduct${random}
+ MP: open concrete drawer by SKU: availabilitySKU${random}-1
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 5 | true | en_US ||
+ MP: open concrete drawer by SKU: availabilitySKU${random}-1
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 50 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 2 | AT | EUR | 50 ||
+ MP: save concrete product
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: availabilityProduct${random} Approve
+ Zed: save abstract product: availabilityProduct${random}
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-1 only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: availabilitySKU${random}-1 Spryker
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Trigger oms
+ Yves: get the last placed order ID by current customer
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-1 only has availability of 2.
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_second_merchant}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state of xxx merchant's shipment: 1 Cancel
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: try add product to the cart from PDP and expect error: Item availabilitySKU${random}-1 only has availability of 5.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: availabilitySKU${random}-1 Spryker
+ Yves: go to AT store 'Home' page if other store not specified:
+ Trigger multistore p&s
+ Yves: go to PDP of the product with sku: availabilitySKU${random} wait_for_p&s=true
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update warehouse:
+ ... || warehouse | unselect store ||
+ ... || Spryker ${merchant_spryker_reference} Warehouse 1 | AT ||
+ Trigger multistore p&s
+ Yves: go to AT store 'Home' page if other store not specified:
+ Yves: go to PDP of the product with sku: availabilitySKU${random}
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} True
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: availabilitySKU${random} Deny
+ ... AND Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Spryker ${merchant_spryker_reference} Warehouse 1 | AT ||
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/checkout/checkout.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/checkout/checkout.robot
new file mode 100644
index 0000000..1da4b2c
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/checkout/checkout.robot
@@ -0,0 +1,374 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/order_comments_steps.robot
+
+*** Test Cases ***
+Business_Unit_Address_on_Checkout
+ [Documentation] Checks that business unit address can be used during checkout
+ Create dynamic customer in DB based_on=${yves_company_user_buyer_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M64933
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: Mr Dynamic Customer, Gurmont Str. 23, 8002 Barcelona
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ Yves: shipping address on the order details page is: Mr. Dynamic Customer Spryker Systems GmbH Gurmont Str. 23 8002 Barcelona, Spain 3490284322
+
+Approval_Process
+ [Documentation] Checks role permissions on checkout and Approval process
+ Create dynamic customer in DB based_on=${yves_company_user_buyer_with_limit_email}
+ Create dynamic customer in DB based_on=${yves_company_user_approver_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping Cart' with name: approvalCart+${random}
+ Yves: go to PDP of the product with sku: M49320
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: select approver on the 'Summary' page: Dynamic Customer (€1,000.00)
+ Yves: 'send the request' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: true ${cancelRequestButton} ${alertWarning} ${quoteStatus}
+ Yves: go to shopping cart page
+ Yves: shopping cart contains/doesn't contain the following elements: true ${lockedCart}
+ Yves: create new 'Shopping Cart' with name: newApprovalCart+${random}
+ Yves: go to PDP of the product with sku: M58314
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: newApprovalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: create new 'Shopping Cart' with name: anotherApprovalCart+${random}
+ Yves: go to PDP of the product with sku: M58314
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: anotherApprovalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: select approver on the 'Summary' page: Dynamic Customer (€1,000.00)
+ Yves: 'send the request' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: true ${cancelRequestButton} ${alertWarning} ${quoteStatus}
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_second_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: approvalCart+${random} Read-only
+ Yves: the following shopping cart is shown: anotherApprovalCart+${random} Read-only
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Waiting
+ Yves: shopping cart with name xxx has the following status: anotherApprovalCart+${random} Waiting
+ Yves: go to the shopping cart through the header with name: approvalCart+${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: 'Summary' page is displayed
+ Yves: 'approve the cart' on the summary page
+ Yves: 'Summary' page is displayed
+ Yves: 'Summary' page contains/doesn't contain: false ${cancelRequestButton} ${alertWarning}
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: approvalCart+${random} Read-only
+ Yves: the following shopping cart is shown: anotherApprovalCart+${random} Read-only
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Approved
+ Yves: shopping cart with name xxx has the following status: anotherApprovalCart+${random} Waiting
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu item in the left bar: Shopping carts
+ Yves: shopping cart with name xxx has the following status: approvalCart+${random} Approved
+ Yves: go to the shopping cart through the header with name: approvalCart+${random}
+ Yves: shopping cart contains/doesn't contain the following elements: true ${lockedCart}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: 'Summary' page is displayed
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+
+Request_for_Quote
+ [Documentation] Checks user can request and receive quote
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M1018212
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: submit new request for quote
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: header contains/doesn't contain: true ${quoteRequestsWidget}
+ Yves: go to 'Agent Quote Requests' page through the header
+ Yves: 'Quote Requests' page is displayed
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Waiting
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page is displayed
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: change price for the product in the quote request with sku xxx on: 403125 500
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: click 'Edit Items' button on the 'Quote Request Details' page
+ Yves: delete product from the shopping cart with sku: 102121
+ Yves: click 'Save and Back to Edit' button on the 'Quote Request Details' page
+ Yves: add the following note to the quote request: Spryker rocks
+ Yves: click 'Save' button on the 'Quote Request Details' page
+ Yves: click 'Send to Agent' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: move mouse over header menu item: ${quoteRequestsWidget}
+ Yves: 'Quote Requests' widget is shown
+ Yves: go to the quote request through the header with reference: ${lastCreatedRfQ}
+ Yves: 'Quote Request Details' page contains the following note: Spryker rocks
+ Yves: click 'Revise' button on the 'Quote Request Details' page
+ Yves: set 'Valid Till' date for the quote request, today +: 1 day
+ Yves: change price for the product in the quote request with sku xxx on: 403125 500
+ Yves: click 'Send to Customer' button on the 'Quote Request Details' page
+ Yves: logout on Yves as a customer
+ Yves: go to the 'Home' page
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Quote Requests
+ Yves: quote request with reference xxx should have status: ${lastCreatedRfQ} Ready
+ Yves: view quote request with reference: ${lastCreatedRfQ}
+ Yves: click 'Convert to Cart' button on the 'Quote Request Details' page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 500
+ Yves: shopping cart doesn't contain the following products: 102121
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: shopping cart contains product with unit price: 403125 EUROKRAFT hand truck - with open shovel - load capacity 400 kg 500
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ [Teardown] Delete dynamic admin user from DB
+
+Unique_URL
+ [Tags] dms-on
+ [Documentation] Bug: https://spryker.atlassian.net/browse/CC-12380
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping Cart' with name: externalCart+${random}
+ Yves: go to PDP of the product with sku: M90806
+ Yves: add product to the shopping cart
+ Yves: go to the shopping cart through the header with name: externalCart+${random}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: get link for external cart sharing
+ Yves: logout on Yves as a customer
+ Yves: go to external URL: ${externalURL}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: Shopping Cart title should be equal: Preview: externalCart+${random}
+ Yves: shopping cart contains the following products: 108302
+
+Split_Delivery
+ [Documentation] Checks split delivery in checkout with new addresses
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 403125 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 107254 | Dr. | First | Last | Second Street | 2 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 419904 | Dr. | First | Last | Third Street | 3 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Dr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: click checkout button: Next
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ [Teardown] Delete dynamic admin user from DB
+
+Multiple_Merchants_Order
+ [Documentation] Checks that order with products and offers of multiple merchants could be placed and it will be split per merchant
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: create dynamic merchant user: Computer Experts
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND MP: login on MP with provided credentials: ${dynamic_expert_merchant}
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer395 | 10 | true ||
+ ... AND MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer193 | 10 | true ||
+ ... AND Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_of_main_merchant_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_multiple_offers_abstract_sku}
+ Yves: merchant's offer/product price should be: Computer Experts ${product_with_multiple_offers_computer_experts_price}
+ Yves: merchant's offer/product price should be: Office King ${product_with_multiple_offers_office_king_price}
+ Yves: select xxx merchant's offer: Computer Experts
+ Yves: product price on the PDP should be: ${product_with_multiple_offers_computer_experts_price}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: ${one_variant_product_of_main_merchant_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${one_variant_product_concrete_sku} Office King
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 DHL Express
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ [Teardown] Delete dynamic admin user from DB
+
+Checkout_Address_Management
+ [Documentation] Bug: CC-30439. Checks that user can change address during the checkout and save new into the address book
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: return to the previous checkout step: Address
+ Yves: billing address same as shipping address: false
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | New | Billing | Changed Street | 098 | 09876 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: save new billing address to address book: false
+ Yves: fill in the following new shipping address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Mr. | First | Last | Shipping Street | 7 | 10247 | Geneva | Switzerland| Spryker | 123456789 | Additional street ||
+ Yves: save new delivery address to address book: true
+ Yves: submit form on the checkout
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: check that user has address exists/doesn't exist: true First Last Shipping Street 7 10247 Geneva Switzerland
+ Yves: check that user has address exists/doesn't exist: false New Billing Changed Street 098 09876 Berlin Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: billing address for the order should be: New Billing, Changed Street 098, 09876 Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 1 Mr First, Last, Shipping Street, 7, Additional street, Spryker, 10247, Geneva, Switzerland
+ [Teardown] Delete dynamic admin user from DB
+
+Comments_in_Cart
+ [Documentation] Add comments to cart and verify comments in Yves and Zed
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: add comment on cart: abc${random}
+ Yves: check comments are visible or not in cart: true abc${random}
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: go to order details page to check comment: abc${random} ${lastPlacedOrder}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: check comment appears at order detailed page in zed: abc${random} ${lastPlacedOrder}
+ [Teardown] Delete dynamic admin user from DB
+
+Comment_Management_in_the_Cart
+ [Documentation] Editing and deleting comments in carts
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: add comment on cart: abc${random}
+ Yves: check comments are visible or not in cart: true abc${random}
+ Yves: edit comment on cart: xyz${random}
+ Yves: check comments are visible or not in cart: true xyz${random}
+ Yves: delete comment on cart
+ Yves: check comments are visible or not in cart: false xyz${random}
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/company/company.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/company/company.robot
new file mode 100644
index 0000000..1ff6027
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/company/company.robot
@@ -0,0 +1,57 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common_ui.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/company_steps.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+
+*** Test Cases ***
+Create_new_company_with_linked_entities_and_customer_in_backoffice
+ [Documentation] Create a new company with linked entities and new customer in backoffice
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Company with provided name: RobotCompany
+ Zed: click Action Button in a table for row that contains: ${created_company} Activate
+ Zed: click Action Button in a table for row that contains: ${created_company} Approve
+ Zed: create new Company Business Unit for the following company: company_name=${created_company} company_id=${created_company_id} business_unit_name=Robot_Business_Unit
+ Zed: create new Company Role with provided permissions: ${created_company} ${created_company_id} RobotRole true View company users See Company Menu
+ Zed: Create new Company User with provided details:
+ ... || email | salutation | first_name | last_name | gender | company | business_unit | role ||
+ ... || sonia+created+cuser+${random}@spryker.com | Ms | Robot | User | Female | ${created_company}| ${created_business_unit} | RobotRole ||
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: sonia+created+cuser+${random}@spryker.com
+ Yves: go to URL: /company/user
+ ${location}= Get Location
+ Should Contain ${location} /company/user msg=Failed to navigate to the 'Company User' page
+ Yves: go to URL: /company/company-role
+ ${location}= Get Location
+ Should Contain ${location} /403 msg=Navigated to the 'Company Role' page despite the lack of permissions
+ [Teardown] Delete dynamic admin user from DB
+
+Create_new_company_user_with_linked_entities_in_storefront
+ [Documentation] Create a new company user on Storefront
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB based_on=${yves_spryker_admin_company_user_email}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new company role: RobotYvesRole+${random}
+ Yves: assign the following permissions to the company role: RobotYvesRole+${random} View company users See Company Menu
+ Yves: create new company business unit: business_unit_name=RobotYvesBusinessUnit+${random} business_unit_email=robot+business+unit+${random}@spryker.com
+ Yves: create new company user: business_unit=RobotYvesBusinessUnit+${random} email=sonia+sf+new+cuser+${random}@spryker.com role=RobotYvesRole+${random} first_name=Sonia last_name=NewUser
+ Yves: logout on Yves as a customer
+ Yves: go to URL: agent/login
+ Yves: login on Yves with provided credentials: ${dynamic_admin_user} agent_assist=${True}
+ Yves: as an agent login under the customer: sonia+sf+new+cuser+${random}@spryker.com
+ Yves: go to URL: /company/user
+ ${location}= Get Location
+ Should Contain ${location} /company/user msg=Failed to navigate to the 'Company User' page
+ Yves: go to URL: /company/company-role
+ ${location}= Get Location
+ Should Contain ${location} /403 msg=Navigated to the 'Company Role' page despite the lack of permissions
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/content/content.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/content/content.robot
new file mode 100644
index 0000000..250ade3
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/content/content.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Content_Management
+ [Documentation] Checks cms content can be edited in zed and that correct cms elements are present on homepage
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Test Page${random} test-page${random} Page Title Page text
+ Yves: go to the 'Home' page
+ Yves: page contains CMS element: Homepage Banners
+ Yves: page contains CMS element: Product Slider Top Sellers
+ Yves: page contains CMS element: Homepage Inspirational block
+ Yves: page contains CMS element: Footer section
+ Yves: go to newly created page by URL: en/test-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Test Page${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/customers/customer.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/customers/customer.robot
new file mode 100644
index 0000000..7751330
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/customers/customer.robot
@@ -0,0 +1,199 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_one
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/company_steps.robot
+
+*** Test Cases ***
+Guest_User_Access_Restrictions
+ [Documentation] Checks that guest users are not able to see: Prices, Availability, Quick Order, "My Account" features
+ Create dynamic customer in DB
+ Yves: go to the 'Home' page
+ Yves: logout on Yves as a customer
+ Yves: header contains/doesn't contain: false ${priceModeSwitcher} ${currencySwitcher}[${env}] ${quickOrderIcon} ${accountIcon} ${shopping_list_icon_header_menu_item}[${env}] ${shoppingCartIcon}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: false ${pdpPriceLocator} ${addToCartButton}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: header contains/doesn't contain: true ${priceModeSwitcher} ${currencySwitcher}[${env}] ${quickOrderIcon} ${accountIcon} ${shopping_list_icon_header_menu_item}[${env}] ${shoppingCartIcon}
+ Yves: company menu 'should' be available for logged in user
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: PDP contains/doesn't contain: true ${pdpPriceLocator} ${addToCartButton}
+ Yves: go to company menu item: Users
+ Yves: 'Company Users' page is displayed
+
+Share_Shopping_Lists
+ [Documentation] Checks that shopping list can be shared
+ [Setup] Run Keywords Create dynamic customer in DB based_on=${yves_company_user_shared_permission_owner_email} email=sonia+sharelist${random}@spryker.com first_name=Share${random} last_name=List${random}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_shared_permission_receiver_email} email=sonia+receivelist${random}@spryker.com first_name=Receive${random} last_name=List${random}
+ Yves: login on Yves with provided credentials: sonia+sharelist${random}@spryker.com
+ Yves: go to 'Shopping Lists' page
+ Yves: 'Shopping Lists' page is displayed
+ Yves: create new 'Shopping List' with name: shareShoppingList+${random}
+ Yves: the following shopping list is shown: shoppingListName=shareShoppingList+${random} shoppingListOwner=Share${random} List${random} shoppingListAccess=Full access
+ Yves: share shopping list with user: shoppingListName=shareShoppingList+${random} customer=Receive${random} List${random} accessLevel=Full access
+ Yves: go to PDP of the product with sku: ${product_with_multiple_offers_abstract_sku}
+ Yves: add product to the shopping list: shareShoppingList+${random}
+ Yves: select xxx merchant's offer: Computer Experts
+ Yves: add product to the shopping list: shareShoppingList+${random}
+ Create New Context
+ Yves: login on Yves with provided credentials: sonia+receivelist${random}@spryker.com
+ Yves: 'Shopping List' widget contains: shareShoppingList+${random} Full access
+ Yves: create new 'Shopping Cart' with name: shoppingListToCart+${random}
+ Yves: go to 'Shopping Lists' page
+ Yves: 'Shopping Lists' page is displayed
+ Yves: the following shopping list is shown: shoppingListName=shareShoppingList+${random} shoppingListOwner=Share${random} List${random} shoppingListAccess=Full access
+ Yves: view shopping list with name: shareShoppingList+${random}
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: add all available products from list to cart
+ Yves: 'Shopping Cart' page is displayed
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ [Teardown] Run Keywords Close Current Context
+
+Share_Shopping_Carts
+ [Documentation] Checks that cart can be shared and used for checkout
+ [Setup] Run Keywords
+ ... Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_shared_permission_owner_email} email=sonia+sharecart${random}@spryker.com first_name=Share${random} last_name=Cart${random}
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_shared_permission_receiver_email} email=sonia+receivecart${random}@spryker.com first_name=Receive${random} last_name=Cart${random}
+ ... AND Zed: create dynamic merchant user: Computer Experts
+ ... AND MP: login on MP with provided credentials: ${dynamic_expert_merchant}
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer395 | 10 | true ||
+ Trigger p&s
+ Yves: login on Yves with provided credentials: sonia+sharecart${random}@spryker.com
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: create new 'Shopping Cart' with name: shoppingCartName+${random}
+ Yves: 'Shopping Carts' widget contains: shoppingCartName+${random} Owner access
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: shoppingCartName+${random} Owner access
+ Yves: share shopping cart with user: shoppingCartName+${random} Cart${random} Receive${random} Full access
+ Yves: go to PDP of the product with sku: ${product_with_multiple_offers_abstract_sku}
+ Yves: change quantity on PDP: 2
+ Yves: add product to the shopping cart
+ Yves: select xxx merchant's offer: Computer Experts
+ Yves: add product to the shopping cart
+ Yves: logout on Yves as a customer
+ Yves: login on Yves with provided credentials: sonia+receivecart${random}@spryker.com
+ Yves: 'Shopping Carts' widget contains: shoppingCartName+${random} Full access
+ Yves: go to 'Shopping Carts' page through the header
+ Yves: 'Shopping Carts' page is displayed
+ Yves: the following shopping cart is shown: shoppingCartName+${random} Full access
+ Yves: go to the shopping cart through the header with name: shoppingCartName+${random}
+ Yves: 'Shopping Cart' page is displayed
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: go to the 'Home' page
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: get the last placed order ID by current customer
+ Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+ Yves: 'Order Details' page is displayed
+ [Teardown] Delete dynamic admin user from DB
+
+Business_on_Behalf
+ [Documentation] Check that BoB user has possibility to change the business unit
+ Create dynamic customer in DB first_name=Oryx${random} last_name=Bob
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Customers Company Users
+ Zed: click Action Button in a table for row that contains: Oryx${random} Attach to BU
+ Zed: attach company user to the following BU with role: Spryker Systems Zurich Admin
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/company/user/select
+ Yves: 'Select Business Unit' page is displayed
+ Yves: 'Business Unit' dropdown contains: Spryker Systems GmbH / Spryker Systems HR department Spryker Systems GmbH / Spryker Systems Zurich
+ [Teardown] Run Keywords Zed: delete company user xxx withing xxx company business unit: Oryx${random} Spryker Systems Zurich
+ ... AND Delete dynamic admin user from DB
+
+User_Account
+ [Documentation] Checks user account pages work + address management
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Order History
+ Yves: 'Order History' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: go to user menu item in the left bar: Newsletter
+ Yves: 'Newsletter' page is displayed
+ Yves: go to user menu item in the left bar: Returns
+ Yves: 'Returns' page is displayed
+ Yves: create a new customer address in profile: Ms ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: true ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Yves: delete user address: Kirncher Str. ${random}
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: 'Addresses' page is displayed
+ Yves: check that user has address exists/doesn't exist: false ${yves_user_first_name} ${random} ${yves_user_last_name} ${random} Kirncher Str. ${random} 7 ${random} Berlin Germany
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a new customer address in profile:
+ ... || email | salutation | first name | last name | address 1 | address 2 | address 3 | city | zip code | country | phone | company ||
+ ... || ${dynamic_customer} | Ms | ${yves_user_first_name}${random} | ${yves_user_last_name}${random} | address 1${random} | address 2 ${random} | address 3 ${random} | Berlin${random} | ${random} | Austria | 123456789 | Spryker${random} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: go to user menu item in the left bar: Addresses
+ Yves: check that user has address exists/doesn't exist: true ${yves_user_first_name}${random} ${yves_user_last_name}${random} address 1${random} address 2 ${random} ${random} Berlin${random} Austria
+ [Teardown] Delete dynamic admin user from DB
+
+Update_Customer_Data
+ [Documentation] Checks customer data can be updated from Yves and Zed
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Ms. | Dynamic | Customer | ${dynamic_customer} ||
+ Yves: update customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name ||
+ ... || Dr. | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assert customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Dr | updated${yves_company_user_buyer_firstname} | updated${yves_company_user_buyer_lastname} ||
+ Zed: update customer profile data:
+ ... || email | salutation | first name | last name ||
+ ... || ${dynamic_customer} | Mr | Dynamic${random} | Customer${random} ||
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to user menu: Overview
+ Yves: 'Overview' page is displayed
+ Yves: go to user menu: Profile
+ Yves: 'Profile' page is displayed
+ Yves: assert customer profile data:
+ ... || salutation | first name | last name | email ||
+ ... || Mr. | Dynamic${random} | Customer${random} | ${dynamic_customer} ||
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/data_exchange/data_exchange.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/data_exchange/data_exchange.robot
new file mode 100644
index 0000000..9ceae62
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/data_exchange/data_exchange.robot
@@ -0,0 +1,121 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/dynamic_entity_steps.robot
+Resource ../../../../resources/steps/api_dynamic_entity_steps.robot
+
+*** Test Cases ***
+Data_exchange_API_download_specification
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: download data exchange api specification should be active: true
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /dynamic-entity/product-abstracts
+ Zed: check that downloaded api specification does not contain: /dynamic-entity/mime-types
+ Zed: delete downloaded api specification
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Zed: download data exchange api specification should be active: false
+ Trigger API specification update
+ Zed: wait until info box is not displayed
+ Zed: download data exchange api specification
+ Zed: check that downloaded api specification contains: /mime-types
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Zed: delete downloaded api specification
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
+
+Data_exchange_API_Configuration_in_Zed
+ [Tags] bapi
+ [Setup] Run Keywords Trigger API specification update
+ ... AND Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: start creation of new data exchange api configuration for db table: spy_mime_type
+ Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || id_mime_type | true | id_mime_type | integer | true | false | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || comment | true | comment | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || extensions | true | extensions | string | true | true | false ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || is_allowed | true | is_allowed | boolean | true | true | true ||
+ Zed: edit data exchange api configuration:
+ ... || field_name | enabled | visible_name | type | creatable | editable | required ||
+ ... || name | true | name | string | true | true | true ||
+ Zed: save data exchange api configuration
+ Trigger API specification update
+ Trigger multistore p&s
+ Zed: wait until info box is not displayed
+ API_test_setup
+ I get access token by user credentials: ${dynamic_admin_user}
+ ### CREATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I set Headers: Content-Type=application/json Authorization=Bearer ${token}
+ I send a POST request: /dynamic-entity/mime-types {"data":[{"name":"POST ${random}","is_allowed":false,"extensions":"fake"}]}
+ Response status code should be: 201
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][0][name] POST ${random}
+ Response body parameter should be: [data][0][is_allowed] False
+ Response body parameter should be: [data][0][extensions] fake
+ Response body parameter should be: [data][0][comment] None
+ Save value to a variable: [data][0][id_mime_type] id_mime_type
+ ### UPDATE TEST MIME TYPE USING DATA EXCHANGE API ###
+ I send a PATCH request: /dynamic-entity/mime-types/${id_mime_type} {"data":{"comment":null,"extensions":"dummy","is_allowed":true,"name":"PATCH ${random}"}}
+ Response status code should be: 200
+ ### GET UPDATE TEST MIME TYPE BY ID ###
+ I send a GET request: /dynamic-entity/mime-types/${id_mime_type}
+ Response status code should be: 200
+ Response header parameter should be: Content-Type application/json
+ Response body parameter should be: [data][name] PATCH ${random}
+ Response body parameter should be: [data][is_allowed] True
+ Response body parameter should be: [data][extensions] dummy
+ Response body parameter should be: [data][comment] None
+ ### DELETE TEST CONFIGURATION AND TEST MIME TYPE FROM DB ###
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: edit data exchange api configuration:
+ ... || table_name | is_enabled ||
+ ... || mime-types | false ||
+ ... AND Zed: save data exchange api configuration
+ ... AND Trigger API specification update
+ ... AND Zed: wait until info box is not displayed
+ ... AND Delete dynamic entity configuration in Database: mime-types
+ ... AND Delete mime_type by id_mime_type in Database: ${id_mime_type}
+ ... AND Trigger API specification update
+ ... AND Delete dynamic admin user from DB
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace.robot
new file mode 100644
index 0000000..e20e00d
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace.robot
@@ -0,0 +1,189 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_account_steps.robot
+Resource ../../../../resources/steps/mp_dashboard_steps.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+
+*** Test Cases ***
+Merchant_Portal_Unauthorized_Access_Redirects_To_Login_Page
+ [Documentation] Check that when root URL for MerchantPortal is opened by unauthorized user he is redirected to login page.
+ Delete All Cookies
+ Go To ${mp_root_url}
+ Wait Until Page Contains Element xpath=//div[@class='login']
+ ${url} Get Location
+ Should Match ${url}/ ${mp_url}
+
+Default_Merchants
+ [Documentation] Checks that default merchants are present in Zed
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: table should contain: Restrictions Merchant
+ Zed: table should contain: Prices Merchant
+ Zed: table should contain: Products Restrictions Merchant
+ [Teardown] Delete dynamic admin user from DB
+
+Shopping_List_Contains_Offers
+ [Documentation] Checks that customer is able to add merchant products and offers to list and merchant relation won't be lost in list and afterwards in cart
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: create new 'Shopping List' with name: shoppingListName${random}
+ Yves: go to PDP of the product with sku: ${product_with_multiple_offers_abstract_sku}
+ Yves: add product to the shopping list: shoppingListName${random}
+ Yves: select xxx merchant's offer: Computer Experts
+ Yves: add product to the shopping list: shoppingListName${random}
+ Yves: view shopping list with name: shoppingListName${random}
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: add all available products from list to cart
+ Yves: 'Shopping Cart' page is displayed
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Spryker
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+
+Search_for_Merchant_Offers_and_Products
+ [Documentation] Checks that through search customer is able to see the list of merchant's products and offers
+ Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: perform search by: Office King
+ Yves: go to the PDP of the first available product on current catalog page
+ Yves: select random varian if variant selector is available
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: perform search by: Spryker
+ Yves: change sorting order on catalog page: Sort by name ascending
+ Yves: go to the PDP of the first available product on current catalog page
+ Yves: select random varian if variant selector is available
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker true
+ Yves: perform search by: ${EMPTY}
+ Yves: select filter value: Merchant Budget Stationery
+ Yves: go to the PDP of the first available product on current catalog page
+ Yves: select random varian if variant selector is available
+ Yves: merchant is (not) displaying in Sold By section of PDP: Budget Stationery true
+
+Merchant_Portal_My_Account
+ [Documentation] Checks that MU can edit personal data in MP
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: Oryx Merchant Edit
+ Zed: create new Merchant User with the following data:
+ ... || e-mail | first name | last name ||
+ ... || sonia+editmu+${random}@spryker.com | FName${random} | LName${random} ||
+ Zed: perform merchant user search by: sonia+editmu+${random}@spryker.com
+ Zed: table should contain non-searchable value: Deactivated
+ Zed: click Action Button in Merchant Users table for row that contains: sonia+editmu+${random}@spryker.com Activate
+ Zed: table should contain non-searchable value: Active
+ Zed: update Zed user:
+ ... || oldEmail | newEmail | password | firstName | lastName ||
+ ... || sonia+editmu+${random}@spryker.com | | ${default_secure_password} | | ||
+ MP: login on MP with provided credentials: sonia+editmu+${random}@spryker.com ${default_secure_password}
+ MP: update merchant personal details with data:
+ ... || firstName | lastName | email | currentPassword | newPassword ||
+ ... || MPUpdatedFName${random} | MPUpdatedLName${random} | | ${default_secure_password} | Updated${default_secure_password} ||
+ MP: click submit button
+ MP: login on MP with provided credentials: sonia+editmu+${random}@spryker.com Updated${default_secure_password}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Users Users
+ Zed: table should contain: MPUpdatedFName${random}
+ Zed: table should contain: MPUpdatedLName${random}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: delete Zed user with the following email: sonia+editmu+${random}@spryker.com
+ ... AND Delete dynamic admin user from DB
+
+Merchant_Portal_Dashboard
+ [Documentation] Checks that merchant user is able to access the dashboard page
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: Oryx Merchant Edit
+ Zed: create new Merchant User with the following data:
+ ... || e-mail | first name | last name ||
+ ... || sonia+dahboard+${random}@spryker.com | DFName${random} | DLName${random} ||
+ Zed: perform merchant user search by: sonia+dahboard+${random}@spryker.com
+ Zed: table should contain non-searchable value: Deactivated
+ Zed: click Action Button in Merchant Users table for row that contains: sonia+dahboard+${random}@spryker.com Activate
+ Zed: table should contain non-searchable value: Active
+ Zed: update Zed user:
+ ... || oldEmail | newEmail | password | firstName | lastName ||
+ ... || sonia+dahboard+${random}@spryker.com | | ${default_secure_password} | | ||
+ Trigger multistore p&s
+ MP: login on MP with provided credentials: sonia+dahboard+${random}@spryker.com ${default_secure_password}
+ MP: click button on dashboard page and check url: Manage Offers /product-offers
+ MP: click button on dashboard page and check url: Add Offer /product-list
+ MP: click button on dashboard page and check url: Manage Orders /orders
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: delete Zed user with the following email: sonia+dahboard+${random}@spryker.com
+ ... AND Delete dynamic admin user from DB
+
+Merchant_Product_Offer_in_Backoffice
+ [Documentation] Check View action and filtration for Mproduct and Moffer in backoffice
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Zed: create dynamic merchant user: Spryker
+ ... AND Zed: create dynamic merchant user: Office King
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || ViewSKU${random} | ViewProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: ViewProduct${random}
+ MP: click on a table row that contains: ViewProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || ViewProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || abstract | 1 | DE | EUR | 100 ||
+ MP: save abstract product
+ MP: click on a table row that contains: ViewProduct${random}
+ MP: open concrete drawer by SKU: ViewSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: ViewProduct${random} Approve
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: ViewSKU${random}-2
+ MP: click on a table row that contains: ViewSKU${random}-2
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | viewMerchantSKU${random} | DE | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | CHF | 100 ||
+ MP: save offer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: filter by merchant: Spryker
+ Zed: table should contain: ViewSKU${random}
+ Zed: click Action Button in a table for row that contains: ViewProduct${random} View
+ Zed: view product page is displayed
+ Zed: view abstract product page contains:
+ ... || merchant | status | store | sku | name ||
+ ... || Spryker | Approved | DE | ViewSKU${random} | ViewProduct${random} ||
+ Zed: go to second navigation item level: Marketplace Offers
+ Zed: filter by merchant: Office King
+ Zed: table should contain: ViewSKU${random}-2
+ Zed: click Action Button in a table for row that contains: ViewSKU${random}-2 View
+ Zed: view offer page is displayed
+ Zed: view offer product page contains:
+ ... || approval status | status | store | sku | name | merchant | merchant sku ||
+ ... || Approved | Active | DE | ViewSKU${random}-2 | ViewProduct${random} | Office King | viewMerchantSKU${random} ||
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: ViewProduct${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_merchant.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_merchant.robot
new file mode 100644
index 0000000..e00d36a
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_merchant.robot
@@ -0,0 +1,121 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/steps/merchant_profile_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_profile_steps.robot
+
+*** Test Cases ***
+Merchant_Profile_Update
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: create dynamic merchant user: Office King
+ [Documentation] Checks that merchant profile could be updated from merchant portal and that changes will be displayed on Yves
+ Yves: go to URL: en/merchant/office-king
+ Yves: assert merchant profile fields:
+ ... || name | email | phone | delivery time | data privacy ||
+ ... || | hi@office-king.nl | +31 123 345 777 | 2-4 days | Office King values the privacy of your personal data. ||
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Profile
+ MP: open profile tab: Online Profile
+ MP: update profile fields with following data:
+ ... || email | phone | delivery time | data privacy ||
+ ... || updated@office-king.nl | +11 222 333 444 | 2-4 weeks | Data privacy updated text ||
+ MP: click submit button
+ Trigger p&s
+ Yves: go to URL: en/merchant/office-king
+ Yves: assert merchant profile fields:
+ ... || name | email | phone | delivery time | data privacy ||
+ ... || | updated@office-king.nl | +11 222 333 444 | 2-4 weeks | Data privacy updated text ||
+ [Teardown] Run Keywords MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ ... AND MP: open navigation menu tab: Profile
+ ... AND MP: open profile tab: Online Profile
+ ... AND MP: update profile fields with following data:
+ ... || email | phone | delivery time | data privacy ||
+ ... || hi@office-king.nl | +31 123 345 777 | 2-4 days | Office King values the privacy of your personal data. ||
+ ... AND MP: click submit button
+ ... AND Trigger p&s
+ ... AND Delete dynamic admin user from DB
+
+Manage_Merchants_from_Backoffice
+ [Documentation] Checks that backoffice admin is able to create, approve, edit merchants
+ [Setup] Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Merchant with the following data:
+ ... || merchant name | merchant reference | e-mail | store | store 2 | en url | de url ||
+ ... || RobotMerchant${random} | RobotMerchantReference${random} | robotMerchant+${random}@test.com | DE | AT | RobotMerchantURL${random} | RobotMerchantURL${random} ||
+ Zed: perform search by: RobotMerchant${random}
+ Zed: table should contain non-searchable value: Inactive
+ Zed: table should contain non-searchable value: Waiting for Approval
+ Zed: table should contain non-searchable value: DE
+ Zed: click Action Button in a table for row that contains: RobotMerchant${random} Activate
+ Zed: click Action Button in a table for row that contains: RobotMerchant${random} Approve Access
+ Zed: perform search by: RobotMerchant${random}
+ Zed: table should contain non-searchable value: Active
+ Zed: table should contain non-searchable value: Approved
+ Zed: click Action Button in a table for row that contains: RobotMerchant${random} Edit
+ Zed: update Merchant on edit page with the following data:
+ ... || merchant name | merchant reference | e-mail | store | en url | de url ||
+ ... || RobotMerchantUpdated${random} | | | | | ||
+ Trigger multistore p&s
+ Yves: go to newly created page by URL: en/merchant/RobotMerchantURL${random}
+ Yves: assert merchant profile fields:
+ ... || name | email | phone | delivery time | data privacy ||
+ ... || RobotMerchantUpdated${random} | | | | ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: RobotMerchantUpdated${random} Edit
+ Zed: update Merchant on edit page with the following data:
+ ... || merchant name | merchant reference | e-mail | uncheck store | uncheck store 2 | en url | de url ||
+ ... || Deactivated${random} | | | DE | AT | | ||
+ Trigger multistore p&s
+ Yves: go to URL and refresh until 404 occurs: ${yves_url}en/merchant/RobotMerchantURL${random}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Marketplace Merchants
+ ... AND Zed: click Action Button in a table for row that contains: Deactivated${random} Deactivate
+ ... AND Trigger multistore p&s
+ ... AND Delete dynamic admin user from DB
+
+Manage_Merchant_Users
+ [Documentation] Checks that backoffice admin is able to create, activate, edit and delete merchant users
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: Office King Edit
+ Zed: create new Merchant User with the following data:
+ ... || e-mail | first name | last name ||
+ ... || sonia+mu+${random}@spryker.com | FName${random} | LName${random} ||
+ Zed: perform merchant user search by: sonia+mu+${random}@spryker.com
+ Zed: table should contain non-searchable value: Deactivated
+ Zed: click Action Button in Merchant Users table for row that contains: sonia+mu+${random}@spryker.com Activate
+ Zed: table should contain non-searchable value: Active
+ Zed: click Action Button in Merchant Users table for row that contains: sonia+mu+${random}@spryker.com Edit
+ Zed: update Merchant User on edit page with the following data:
+ ... || e-mail | first name | last name ||
+ ... || | UpdatedName${random} | ||
+ Zed: perform merchant user search by: sonia+mu+${random}@spryker.com
+ Zed: table should contain non-searchable value: UpdatedName${random}
+ Zed: update Zed user:
+ ... || oldEmail | newEmail | password | firstName | lastName ||
+ ... || sonia+mu+${random}@spryker.com | | ${default_secure_password} | | ||
+ MP: login on MP with provided credentials: sonia+mu+${random}@spryker.com ${default_secure_password}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: Office King Edit
+ Zed: go to tab by link href that contains: merchant-user
+ Zed: click Action Button in Merchant Users table for row that contains: sonia+mu+${random}@spryker.com Deactivate
+ Zed: table should contain non-searchable value: Deactivated
+ MP: login on MP with provided credentials and expect error: sonia+mu+${random}@spryker.com ${default_secure_password}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Marketplace Merchants
+ ... AND Zed: click Action Button in a table for row that contains: Office King Edit
+ ... AND Zed: go to tab by link href that contains: merchant-user
+ ... AND Zed: click Action Button in Merchant Users table for row that contains: sonia+mu+${random}@spryker.com Delete
+ ... AND Zed: submit the form
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_product.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_product.robot
new file mode 100644
index 0000000..88f51ab
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_manage_product.robot
@@ -0,0 +1,135 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+
+*** Test Cases ***
+Manage_Merchant_Product
+ [Documentation] Checks that MU and BO user can manage merchant abstract and concrete products + add new concrete product
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Repeat Keyword 3 Trigger multistore p&s
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || manageSKU${random} | manageProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: manageProduct${random}
+ MP: click on a table row that contains: manageProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || manageProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 1 | DE | EUR | 100 | 90 ||
+ MP: save abstract product
+ Trigger p&s
+ MP: click on a table row that contains: manageProduct${random}
+ MP: open concrete drawer by SKU: manageSKU${random}-1
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: open concrete drawer by SKU: manageSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 3 | true | en_US ||
+ MP: open concrete drawer by SKU: manageSKU${random}-1
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 50 ||
+ MP: save concrete product
+ Trigger p&s
+ MP: open concrete drawer by SKU: manageSKU${random}-2
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 20 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | quantity ||
+ ... || concrete | 2 | DE | EUR | 10 | 2 ||
+ MP: save concrete product
+ Trigger p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: manageProduct${random} Approve
+ Zed: save abstract product: manageProduct${random}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: manageSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: change variant of the product on PDP on: Item
+ Yves: product price on the PDP should be: €50.00 wait_for_p&s=true
+ Yves: merchant's offer/product price should be: Office King €50.00
+ Yves: reset selected variant of the product on PDP
+ Yves: change variant of the product on PDP on: Box
+ Reload
+ Yves: change quantity using '+' or '-' button № times: + 5
+ Yves: product price on the PDP should be: €10.00
+ Yves: merchant's offer/product price should be: Office King €10.00
+ Yves: try add product to the cart from PDP and expect error: Item manageSKU${random}-2 only has availability of 3.
+ Yves: change quantity using '+' or '-' button № times: + 2
+ Yves: product price on the PDP should be: €10.00
+ Yves: merchant's offer/product price should be: Office King €10.00
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: manageSKU${random}-2 manageProduct${random} 10.00
+ Yves: assert merchant of product in cart or list: manageSKU${random}-2 Office King
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: perform search by: manageProduct${random}
+ MP: click on a table row that contains: manageProduct${random}
+ MP: add new concrete product:
+ ... || first attribute | first attribute value | second attribute | second attribute value ||
+ ... || packaging_unit | 5-pack | material | Aluminium ||
+ MP: save abstract product
+ MP: perform search by: manageProduct${random}
+ MP: click on a table row that contains: manageProduct${random}
+ MP: open concrete drawer by SKU: manageSKU${random}-3
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 3 | true | en_US ||
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: manageProduct${random} View
+ Zed: view product page is displayed
+ Zed: view abstract product page contains:
+ ... || merchant | status | store | sku | name | variants count ||
+ ... || Office King | Approved | DE | manageSKU${random} | manageProduct${random} | 3 ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | DE | gross | default | € | 110.00 ||
+ Zed: update abstract product data:
+ ... || productAbstract | store | name en | name de | new from | new to ||
+ ... || manageSKU${random} | AT | ENUpdatedmanageProduct${random} | DEUpdatedmanageProduct${random} | 01.01.2020 | 01.01.2030 ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | DE | gross | default | € | 110.00 ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || manageSKU${random} | manageSKU${random}-3 | DE | gross | default| € | 15.00 ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: go to second navigation item level: Catalog Products
+ Zed: table should contain: ENUpdatedmanageProduct${random}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: manageSKU${random}
+ Yves: product name on PDP should be: ENUpdatedmanageProduct${random}
+ Yves: product price on the PDP should be: €110.00 wait_for_p&s=true
+ Yves: change variant of the product on PDP on: 5-pack
+ Yves: product price on the PDP should be: €15.00 wait_for_p&s=true
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: manageSKU${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offer_volume_prices.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offer_volume_prices.robot
new file mode 100644
index 0000000..b42c983
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offer_volume_prices.robot
@@ -0,0 +1,101 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+
+*** Test Cases ***
+Merchant_Portal_Offer_Volume_Prices
+ [Documentation] Checks that merchant is able to create new offer with volume prices and it will be displayed on Yves. Fallback to default price after delete
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Zed: create dynamic merchant user: Spryker
+ Trigger multistore p&s
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || OfferSKU${random} | OfferNewProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: OfferNewProduct${random}
+ MP: click on a table row that contains: OfferNewProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || OfferNewProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default ||
+ ... || abstract | 1 | Default | DE | EUR | 100 ||
+ MP: save abstract product
+ Trigger p&s
+ MP: click on a table row that contains: OfferNewProduct${random}
+ MP: open concrete drawer by SKU: OfferSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ Trigger p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: OfferNewProduct${random} Approve
+ Zed: save abstract product: OfferNewProduct${random}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: OfferSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker true
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: OfferSKU${random}-2
+ MP: click on a table row that contains: OfferSKU${random}-2
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | volumeMerchantSKU${random} | DE | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 1 | DE | EUR | 200 | 1 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 2 | DE | EUR | 10 | 2 ||
+ MP: save offer
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: OfferSKU${random}
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: merchant's offer/product price should be: Office King €200.00
+ Yves: select xxx merchant's offer: Office King
+ Yves: try reloading page if element is/not appear: ${pdp_product_not_available_text} False
+ Yves: change quantity on PDP: 2
+ Yves: product price on the PDP should be: €10.00
+ Yves: merchant's offer/product price should be: Office King €10.00
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: assert merchant of product in cart or list: OfferSKU${random}-2 Office King
+ Yves: shopping cart contains product with unit price: OfferSKU${random}-2 OfferNewProduct${random} 10
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Offers
+ MP: perform search by: OfferSKU${random}-2
+ MP: click on a table row that contains: volumeMerchantSKU${random}
+ MP: delete offer price row that contains quantity: 2
+ MP: save offer
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: OfferSKU${random}
+ Yves: select xxx merchant's offer: Office King
+ Yves: change quantity on PDP: 2
+ Yves: product price on the PDP should be: €200.00
+ Yves: merchant's offer/product price should be: Office King €200.00
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: OfferSKU${random}-2 OfferNewProduct${random} 200
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: OfferNewProduct${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_boffice.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_boffice.robot
new file mode 100644
index 0000000..4533fb0
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_boffice.robot
@@ -0,0 +1,80 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/mp_profile_steps.robot
+Resource ../../../../resources/pages/yves/yves_merchant_profile.robot
+
+*** Test Cases ***
+Merchant_Profile_Set_to_Inactive_from_Backoffice
+ [Documentation] Checks that backoffice admin is able to deactivate merchant and then it's profile, products and offers won't be displayed on Yves
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Merchant with the following data:
+ ... || merchant name | merchant reference | e-mail | store | store 2 | en url | de url | approved | contact_first_name | contact_last_name ||
+ ... || offline_from_BO${random} | offline_from_BO_reference${random} | offline_from_BO+${random}@test.com | DE | AT | offline-from-bo${random} | offline-from-bo${random} | true | FirstOffBO${random} | LastOffBO${random} ||
+ Zed: create dynamic merchant user: offline_from_BO${random} merchant_user_email=sonia+offline+bo${random}@spryker.com
+ Zed: create dynamic merchant user: Spryker
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || offlineBO${random} | offlineBO${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: offlineBO${random}
+ MP: click on a table row that contains: offlineBO${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || offlineBO${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || abstract | 1 | DE | EUR | 100 ||
+ MP: save abstract product
+ Trigger multistore p&s
+ MP: click on a table row that contains: offlineBO${random}
+ MP: open concrete drawer by SKU: offlineBO${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: login on MP with provided credentials: sonia+offline+bo${random}@spryker.com ${default_secure_password}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: offlineBO${random}-2
+ MP: click on a table row that contains: offlineBO${random}-2
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | offlineBOoffer${random} | DE | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | EUR | 200 ||
+ MP: save offer
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: offlineBO${random} Approve
+ Zed: save abstract product: offlineBO${random}
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to newly created page by URL: url=en/merchant/offline-from-bo${random} delay=5s iterations=26
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: offlineBO${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: offline_from_BO${random} true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Merchants
+ Zed: click Action Button in a table for row that contains: offline_from_BO${random} Deactivate
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to URL: en/merchant/offline-from-mp${random}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: try reloading page if element is/not appear: ${merchant_profile_main_content_locator} false
+ Yves: go to PDP of the product with sku: offlineBO${random}
+ Yves: merchant is (not) displaying in Sold By section of PDP: offline_from_BO${random} false
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_mportal.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_mportal.robot
new file mode 100644
index 0000000..6562d4d
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_offline_profile_mportal.robot
@@ -0,0 +1,81 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/mp_profile_steps.robot
+Resource ../../../../resources/pages/yves/yves_merchant_profile.robot
+
+*** Test Cases ***
+Merchant_Profile_Set_to_Offline_from_MP
+ [Documentation] Checks that merchant is able to set store offline and then his profile, products and offers won't be displayed on Yves
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Merchant with the following data:
+ ... || merchant name | merchant reference | e-mail | store | store 2 | en url | de url | approved | contact_first_name | contact_last_name ||
+ ... || offline_from_MP${random} | offline_from_MP_reference${random} | offline_from_MP+${random}@test.com | DE | AT | offline-from-mp${random} | offline-from-mp${random} | true | FirstOffMP${random} | LastOffMP${random} ||
+ Zed: create dynamic merchant user: offline_from_MP${random} merchant_user_email=sonia+offline+mp${random}@spryker.com
+ Zed: create dynamic merchant user: Spryker
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || offlineMP${random} | offlineMP${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: offlineMP${random}
+ MP: click on a table row that contains: offlineMP${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || offlineMP${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || abstract | 1 | DE | EUR | 100 ||
+ MP: save abstract product
+ Trigger multistore p&s
+ MP: click on a table row that contains: offlineMP${random}
+ MP: open concrete drawer by SKU: offlineMP${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: login on MP with provided credentials: sonia+offline+mp${random}@spryker.com ${default_secure_password}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: offlineMP${random}-2
+ MP: click on a table row that contains: offlineMP${random}-2
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | offlineMPoffer${random} | DE | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | EUR | 200 ||
+ MP: save offer
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: offlineMP${random} Approve
+ Zed: save abstract product: offlineMP${random}
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to newly created page by URL: url=en/merchant/offline-from-mp${random} delay=5s iterations=26
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: offlineMP${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: offline_from_MP${random} true
+ MP: login on MP with provided credentials: sonia+offline+mp${random}@spryker.com ${default_secure_password}
+ MP: open navigation menu tab: Profile
+ MP: open profile tab: Online Profile
+ MP: change store status to: offline
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to URL: en/merchant/offline-from-mp${random}
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: try reloading page if element is/not appear: ${merchant_profile_main_content_locator} false
+ Yves: go to PDP of the product with sku: offlineMP${random}
+ Yves: merchant is (not) displaying in Sold By section of PDP: offline_from_MP${random} false
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_oms.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_oms.robot
new file mode 100644
index 0000000..8863645
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_oms.robot
@@ -0,0 +1,82 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/mp_orders_steps.robot
+
+*** Test Cases ***
+Fulfill_Order_from_Merchant_Portal
+ [Documentation] Checks that merchant is able to process his order through OMS from merchant portal
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Zed: create dynamic merchant user: Computer Experts
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND MP: login on MP with provided credentials: ${dynamic_expert_merchant}
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer395 | 10 | true ||
+ ... AND MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer193 | 10 | true ||
+ ... AND MP: change offer stock:
+ ... || offer | stock quantity | is never out of stock ||
+ ... || offer220 | 10 | true ||
+ ... AND Create dynamic customer in DB
+ ... AND Trigger p&s
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${product_with_multiple_offers_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: select xxx merchant's offer: Computer Experts
+ Yves: add product to the shopping cart
+ Yves: select xxx merchant's offer: Office King
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M22660
+ Yves: select xxx merchant's offer: Office King
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Office King
+ Yves: assert merchant of product in cart or list: ${product_with_multiple_offers_concrete_sku} Computer Experts
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method for the shipment: 1 DHL Standard
+ Yves: select the following shipping method for the shipment: 2 Hermes Same Day
+ Yves: select the following shipping method for the shipment: 3 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: trigger all matching states inside xxx order: ${lastPlacedOrder} skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: wait for order item to be in state: ${product_with_multiple_offers_concrete_sku} sent to merchant 2
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Orders
+ MP: wait for order to appear: ${lastPlacedOrder}--${merchant_office_king_reference}
+ MP: click on a table row that contains: ${lastPlacedOrder}--${merchant_office_king_reference}
+ MP: order grand total should be: €32.78
+ MP: update order state using header button: Ship
+ MP: order states on drawer should contain: Shipped
+ MP: switch to the tab: Items
+ MP: change order item state on: 423172 Deliver
+ MP: switch to the tab: Items
+ MP: order item state should be: 427915 shipped
+ MP: order item state should be: 423172 delivered
+ MP: update order state using header button: Deliver
+ MP: order states on drawer should contain: Delivered
+ MP: switch to the tab: Items
+ MP: order item state should be: 427915 delivered
+ MP: order item state should be: 423172 delivered
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_prices.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_prices.robot
new file mode 100644
index 0000000..a64f9e2
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_prices.robot
@@ -0,0 +1,103 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Merchant_Portal_Customer_Specific_Prices
+ [Documentation] Checks that customer will see product/offer prices specified by merchant for his business unit
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB based_on=${yves_company_user_custom_merchant_prices_email}
+ ... AND Zed: create dynamic merchant user: Spryker
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: perform search by: ${one_variant_product_of_main_merchant_abstract_sku}
+ MP: click on a table row that contains: ${one_variant_product_of_main_merchant_abstract_sku}
+ MP: open concrete drawer by SKU: ${one_variant_product_of_main_merchant_concrete_sku}
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default ||
+ ... || concrete | 1 | 5 - Spryker Systems GmbH | DE | EUR | 100 ||
+ MP: save concrete product
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_of_main_merchant_abstract_sku}
+ Yves: merchant's offer/product price should be: Spryker €100.00
+ MP: login on MP with provided credentials: ${merchant_spryker_email}
+ MP: open navigation menu tab: Products
+ MP: perform search by: ${one_variant_product_of_main_merchant_abstract_sku}
+ MP: click on a table row that contains: ${one_variant_product_of_main_merchant_abstract_sku}
+ MP: open concrete drawer by SKU: ${one_variant_product_of_main_merchant_concrete_sku}
+ MP: delete product price row that contains text: 5 - Spryker Systems GmbH
+ MP: save concrete product
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_of_main_merchant_abstract_sku}
+ Yves: merchant's offer/product price should be: Spryker €632.12
+ [Teardown] Delete dynamic admin user from DB
+
+Merchant_Product_Original_Price
+ [Documentation] checks that Original price is displayed on the PDP and in Catalog
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || originalSKU${random} | originalProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: originalProduct${random}
+ MP: click on a table row that contains: originalProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || originalProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 1 | DE | EUR | 100 | 150 ||
+ MP: save abstract product
+ MP: click on a table row that contains: originalProduct${random}
+ MP: open concrete drawer by SKU: originalSKU${random}-1
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: open concrete drawer by SKU: originalSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 3 | true | en_US ||
+ MP: open concrete drawer by SKU: originalSKU${random}-1
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 50 ||
+ MP: save concrete product
+ MP: open concrete drawer by SKU: originalSKU${random}-2
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 20 ||
+ MP: save concrete product
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: originalProduct${random} Approve
+ Zed: save abstract product: originalProduct${random}
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to URL: en/search?q=originalSKU${random}
+ Try reloading page until element is/not appear: ${catalog_product_card_locator} true 21 5s
+ Yves: 1st product card in catalog (not)contains: Price €100.00
+ Yves: 1st product card in catalog (not)contains: Original Price €150.00
+ Yves: go to PDP of the product with sku: originalSKU${random} wait_for_p&s=true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Yves: product original price on the PDP should be: €150.00
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: originalSKU${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_and_offer.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_and_offer.robot
new file mode 100644
index 0000000..35a6ea6
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_and_offer.robot
@@ -0,0 +1,138 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+*** Test Cases ***
+Create_and_Approve_New_Merchant_Product
+ [Documentation] Checks that merchant is able to create new multi-SKU product and marketplace operator is able to approve it in BO
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Trigger p&s
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || SKU${random} | NewProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: NewProduct${random}
+ MP: click on a table row that contains: NewProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || NewProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default ||
+ ... || abstract | 1 | Default | DE | EUR | 100 ||
+ MP: save abstract product
+ MP: click on a table row that contains: NewProduct${random}
+ MP: open concrete drawer by SKU: SKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: save abstract product
+ Trigger p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: NewProduct${random} Approve
+ Zed: save abstract product: NewProduct${random}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: SKU${random} wait_for_p&s=true
+ Save current URL
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: NewProduct${random} Deny
+ Trigger p&s
+ Yves: go to the 'Home' page
+ Yves: go to URL and refresh until 404 occurs: ${url}
+ [Teardown] Delete dynamic admin user from DB
+
+Create_New_Offer
+ [Documentation] Checks that merchant is able to create new offer and it will be displayed on Yves
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Zed: create dynamic merchant user: Spryker
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || SprykerSKU${random} | SprykerProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: SprykerProduct${random}
+ MP: click on a table row that contains: SprykerSKU${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || SprykerProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default ||
+ ... || abstract | 1 | Default | DE | EUR | 100 ||
+ MP: save abstract product
+ MP: click on a table row that contains: SprykerSKU${random}
+ MP: open concrete drawer by SKU: SprykerSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: SprykerSKU${random} Approve
+ Zed: save abstract product: SprykerSKU${random}
+ Trigger p&s
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: SprykerSKU${random}-2
+ MP: click on a table row that contains: SprykerSKU${random}-2
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | stock quantity ||
+ ... || true | merchantSKU${random} | DE | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | EUR | 200 ||
+ MP: save offer
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: SprykerSKU${random}-2 wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: merchant's offer/product price should be: Office King €200.00
+ Yves: select xxx merchant's offer: Office King
+ Yves: add product to the shopping cart wait_for_p&s=true
+ Yves: go to shopping cart page
+ Yves: 'Shopping Cart' page is displayed
+ Yves: assert merchant of product in cart or list: SprykerSKU${random}-2 Office King
+ Yves: shopping cart contains product with unit price: SprykerSKU${random}-2 SprykerProduct${random} 200
+ [Teardown] Delete dynamic admin user from DB
+
+Approve_Offer
+ [Documentation] Checks that marketplace operator is able to approve or deny merchant's offer and it will be available or not in store due to this status
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Offers
+ Zed: select merchant in filter: Office King
+ Zed: click Action Button in a table for row that contains: ${product_with_never_out_of_stock_offer_concrete_sku} Deny
+ Trigger p&s
+ Yves: go to the 'Home' page
+ Yves: go to PDP of the product with sku: ${product_with_never_out_of_stock_offer_abstract_sku}
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King false
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Marketplace Offers
+ Zed: select merchant in filter: Office King
+ Zed: click Action Button in a table for row that contains: ${product_with_never_out_of_stock_offer_concrete_sku} Approve
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${product_with_never_out_of_stock_offer_abstract_sku}
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: select xxx merchant's offer: Office King
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_volume_prices.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_volume_prices.robot
new file mode 100644
index 0000000..38d7926
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/marketplace/marketplace_product_volume_prices.robot
@@ -0,0 +1,81 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_two
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+
+
+*** Test Cases ***
+Merchant_Portal_Product_Volume_Prices
+ [Documentation] Checks that merchant is able to create new multi-SKU product with volume prices. Fallback to default price after delete.
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ Trigger multistore p&s
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || VPSKU${random} | VPNewProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: VPNewProduct${random}
+ MP: click on a table row that contains: VPNewProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | tax set ||
+ ... || VPNewProduct${random} | DE | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default ||
+ ... || abstract | 1 | Default | DE | EUR | 100 ||
+ MP: fill product price values:
+ ... || product type | row number | customer | store | currency | gross default | quantity ||
+ ... || abstract | 2 | Default | DE | EUR | 10 | 2 ||
+ MP: save abstract product
+ Trigger p&s
+ MP: click on a table row that contains: VPNewProduct${random}
+ MP: open concrete drawer by SKU: VPSKU${random}-2
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ Repeat Keyword 3 Trigger p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: VPNewProduct${random} Approve
+ Zed: save abstract product: VPNewProduct${random}
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: VPSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: product price on the PDP should be: €100.00 wait_for_p&s=true
+ Reload
+ Yves: change quantity on PDP: 2
+ Yves: product price on the PDP should be: €10.00
+ Yves: merchant's offer/product price should be: Office King €10.00
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: VPSKU${random}-2 VPNewProduct${random} 10.00
+ Yves: assert merchant of product in cart or list: VPSKU${random}-2 Office King
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: perform search by: VPNewProduct${random}
+ MP: click on a table row that contains: VPNewProduct${random}
+ MP: delete product price row that contains quantity: 2
+ MP: save abstract product
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: VPSKU${random}
+ Yves: change quantity on PDP: 2
+ Yves: product price on the PDP should be: €100.00
+ Yves: merchant's offer/product price should be: Office King €100.00
+ Yves: go to shopping cart page
+ Yves: shopping cart contains product with unit price: VPSKU${random}-2 VPNewProduct${random} 100.00
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Catalog Products
+ ... AND Zed: click Action Button in a table for row that contains: VPNewProduct${random} Deny
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/merchandising/merchandising.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/merchandising/merchandising.robot
new file mode 100644
index 0000000..5a46631
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/merchandising/merchandising.robot
@@ -0,0 +1,87 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Product_labels
+ [Documentation] Checks that products have labels on PLP and PDP
+ Trigger product labels update
+ Yves: go to first navigation item level: Sale %
+ Yves: 1st product card in catalog (not)contains: Sale label true
+ Yves: go to the PDP of the first product on open catalog page
+ Yves: PDP contains/doesn't contain: true ${pdp_sales_label}[${env}]
+ Yves: go to first navigation item level: New
+ Yves: 1st product card in catalog (not)contains: New label true
+ Yves: go to the PDP of the first product on open catalog page
+ Yves: PDP contains/doesn't contain: true ${pdp_new_label}[${env}]
+
+Product_Relations
+ [Documentation] Checks related product on PDP and upsell products in cart
+ [Setup] Create dynamic customer in DB
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: PDP contains/doesn't contain: true ${relatedProducts}
+ Yves: go to PDP of the product with sku: ${product_with_relations_upselling_sku}
+ Yves: PDP contains/doesn't contain: false ${relatedProducts}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: shopping cart contains/doesn't contain the following elements: true ${upSellProducts}
+
+#### Product Sets feature is not present in marketplace for now ####
+# Product_Sets
+# [Tags] skip-due-to-refactoring
+# [Documentation] Checks that product set can be added into cart
+# [Setup] Run keywords Yves: login on Yves with provided credentials: ${yves_company_user_buyer_email}
+# ... AND Yves: create new 'Shopping Cart' with name: productSetsCart+${random}
+# Yves: go to URL: en/product-sets
+# Yves: 'Product Sets' page contains the following sets: The Presenter's Set Basic office supplies The ultimate data disposal set
+# Yves: view the following Product Set: Basic office supplies
+# Yves: 'Product Set' page contains the following products: Clairefontaine Collegeblock 8272C DIN A5, 90 sheets
+# Yves: change variant of the product on CMS page on: Clairefontaine Collegeblock 8272C DIN A5, 90 sheets lined
+# Yves: add all products to the shopping cart from Product Set
+# Yves: shopping cart contains the following products: 421344 420687 421511 423452
+# [Teardown] Yves: delete 'Shopping Cart' with name: productSetsCart+${random}
+
+# ### Configurable Bundles feature is not present in marketplace for now ####
+# Configurable_Bundle
+# [Tags] skip-due-to-refactoring
+# [Documentation] Checks checkout with the configurable bundle
+# [Setup] Run keywords Yves: login on Yves with provided credentials: ${yves_company_user_manager_and_buyer_email}
+# ... AND Yves: delete all shopping carts
+# ... AND Yves: create new 'Shopping Cart' with name: confBundle+${random}
+# Yves: go to second navigation item level: More Configurable Bundle
+# Yves: 'Choose Bundle to configure' page is displayed
+# Yves: choose bundle template to configure: Presentation bundle
+# Yves: select product in the bundle slot: Slot 5 408104
+# Yves: select product in the bundle slot: Slot 6 423172
+# Yves: go to 'Summary' step in the bundle configurator
+# Yves: add products to the shopping cart in the bundle configurator
+# Yves: go to second navigation item level: More Configurable Bundle
+# Yves: 'Choose Bundle to configure' page is displayed
+# Yves: choose bundle template to configure: Presentation bundle
+# Yves: select product in the bundle slot: Slot 5 421539
+# Yves: select product in the bundle slot: Slot 6 424551
+# Yves: go to 'Summary' step in the bundle configurator
+# Yves: add products to the shopping cart in the bundle configurator
+# Yves: change quantity of the configurable bundle in the shopping cart on: Presentation bundle 2
+# Yves: click on the 'Checkout' button in the shopping cart
+# Yves: billing address same as shipping address: true
+# Yves: select the following existing address on the checkout as 'shipping' address and go next: ${yves_company_user_manager_and_buyer_address}
+# Yves: select the following shipping method on the checkout and go next: Express
+# Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+# Yves: accept the terms and conditions: true
+# Yves: 'submit the order' on the summary page
+# Yves: 'Thank you' page is displayed
+# Yves: go to user menu: Order History
+# Yves: 'Order History' page is displayed
+# Yves: get the last placed order ID by current customer
+# Yves: 'View Order/Reorder/Return' on the order history page: View Order ${lastPlacedOrder}
+# Yves: 'View Order' page is displayed
+# Yves: 'Order Details' page contains the following product title N times: Presentation bundle 3
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/misc/static_demodata_set.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/misc/static_demodata_set.robot
new file mode 100644
index 0000000..714add3
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/misc/static_demodata_set.robot
@@ -0,0 +1,97 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure static-set
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/common/common_zed.robot
+Resource ../../../../resources/steps/minimum_order_value_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/steps/zed_discount_steps.robot
+Resource ../../../../resources/steps/zed_availability_steps.robot
+
+*** Test Cases ***
+Minimum_Order_Value
+ [Documentation] checks that global minimum and maximum order thresholds can be applied
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold fixed fee | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | 5 | EN minimum {{threshold}} | DE minimum {{threshold}} | 400 | EN max {{threshold}} | DE max {{threshold}} | Soft Threshold with fixed fee | 100000 | 9 | EN fixed {{fee}} fee | DE fixed {{fee}} fee ||
+ Trigger p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: submit form on the checkout
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: select the following shipping method for the shipment: 2 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: hard threshold is applied with the following message: €400.00
+ Yves: go to shopping cart page
+ Yves: delete product from the shopping cart with sku: 403125
+ Yves: soft threshold surcharge is added in the cart: €9.00
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: soft threshold surcharge is added on summary page: €9.00
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €227.29
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change global threshold settings:
+ ... || store & currency | minimum hard value | minimum hard en message | minimum hard de message | maximum hard value | maximum hard en message | maximum hard de message | soft threshold | soft threshold value | soft threshold en message | soft threshold de message ||
+ ... || DE - Euro [EUR] | ${SPACE} | ${SPACE} | ${SPACE} | 10000.00 | The cart value cannot be higher than {{threshold}}. Please remove some items to proceed with the order | Der Warenkorbwert darf nicht höher als {{threshold}} sein. Bitte entfernen Sie einige Artikel, um mit der Bestellung fortzufahren | None | ${EMPTY} | ${EMPTY} | ${EMPTY} ||
+ ... AND Delete dynamic admin user from DB
+
+Discounts
+ [Documentation] Discounts, Promo Products, and Coupon Codes
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: change product stock: M21777 421538 true 10
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a discount and activate it: voucher Percentage 5 sku = '*' test${random} discountName=Voucher Code 5% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 10 sku = '*' discountName=Cart Rule 10% ${random}
+ Zed: create a discount and activate it: cart rule Percentage 100 discountName=Promotional Product 100% ${random} promotionalProductDiscount=True promotionalProductAbstractSku=M29503 promotionalProductQuantity=2
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M21777
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: apply discount voucher to cart: test${random}
+ Yves: discount is applied: voucher Voucher Code 5% ${random} - €0.72
+ Yves: discount is applied: cart rule Cart Rule 10% ${random} - €1.44
+ Yves: promotional product offer is/not shown in cart: true
+ Yves: change quantity of promotional product and add to cart: + 1
+ Yves: shopping cart contains the following products: 419873 421538
+ Yves: discount is applied: cart rule Promotional Product 100% ${random} - €123.10
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €18.11
+ [Teardown] Run keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: Deactivate Following Discounts From Overview Page: Voucher Code 5% ${random} Cart Rule 10% ${random} Promotional Product 100% ${random}
+ ... AND Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_catalog.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_catalog.robot
new file mode 100644
index 0000000..29869fe
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_catalog.robot
@@ -0,0 +1,142 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_products_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/mp_offers_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+
+*** Test Cases ***
+Multistore_Product_Offer
+ [Documentation] check product and offer multistore functionality
+ [Setup] Run Keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: Office King
+ ... AND Zed: create dynamic merchant user: Spryker
+ MP: login on MP with provided credentials: ${dynamic_king_merchant}
+ MP: open navigation menu tab: Products
+ MP: click on create new entity button: Create Product
+ MP: create multi sku product with following data:
+ ... || product sku | product name | first attribute name | first attribute first value | first attribute second value | second attribute name | second attribute value ||
+ ... || multistoreSKU${random} | multistoreProduct${random} | packaging_unit | Item | Box | material | Aluminium ||
+ MP: perform search by: multistoreProduct${random}
+ MP: click on a table row that contains: multistoreProduct${random}
+ MP: fill abstract product required fields:
+ ... || product name | store | store 2 | tax set ||
+ ... || multistoreProduct${random} | DE | AT | Standard Taxes ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 1 | DE | EUR | 100 | 90 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default | gross original ||
+ ... || abstract | 2 | AT | EUR | 300 | 90 ||
+ MP: save abstract product
+ Trigger multistore p&s
+ MP: click on a table row that contains: multistoreProduct${random}
+ MP: open concrete drawer by SKU: multistoreSKU${random}-1
+ MP: fill concrete product fields:
+ ... || is active | stock quantity | use abstract name | searchability ||
+ ... || true | 100 | true | en_US ||
+ MP: open concrete drawer by SKU: multistoreSKU${random}-1
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 1 | DE | EUR | 50 ||
+ MP: fill product price values:
+ ... || product type | row number | store | currency | gross default ||
+ ... || concrete | 2 | AT | EUR | 55 ||
+ MP: save concrete product
+ Trigger multistore p&s
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: go to second navigation item level: Catalog Products
+ Zed: click Action Button in a table for row that contains: multistoreSKU${random} Approve
+ Zed: save abstract product: multistoreSKU${random}
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: multistoreSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: product price on the PDP should be: €50.00 wait_for_p&s=true
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Offers
+ MP: click on create new entity button: Add Offer
+ MP: perform search by: multistoreSKU${random}-1
+ MP: click on a table row that contains: multistoreSKU${random}-1
+ MP: fill offer fields:
+ ... || is active | merchant sku | store | store 2 | stock quantity ||
+ ... || true | multistoreMerchantSKU${random} | DE | AT | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default ||
+ ... || 1 | DE | CHF | 100 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 2 | DE | EUR | 200 | 1 ||
+ MP: add offer price:
+ ... || row number | store | currency | gross default | quantity ||
+ ... || 3 | AT | EUR | 10 | 1 ||
+ MP: save offer
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: multistoreSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker true
+ Yves: merchant's offer/product price should be: Spryker €200.00
+ Yves: go to AT store 'Home' page if other store not specified:
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: multistoreSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Office King true
+ Yves: product price on the PDP should be: €55.00 wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker true
+ Yves: merchant's offer/product price should be: Spryker €10.00
+ MP: login on MP with provided credentials: ${dynamic_spryker_merchant}
+ MP: open navigation menu tab: Offers
+ MP: perform search by: multistoreSKU${random}-1
+ MP: click on a table row that contains: multistoreSKU${random}-1
+ MP: fill offer fields:
+ ... || is active | unselect store ||
+ ... || true | AT ||
+ MP: save offer
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: go to AT store 'Home' page if other store not specified:
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: multistoreSKU${random} wait_for_p&s=true
+ Yves: merchant is (not) displaying in Sold By section of PDP: Spryker false
+ Save current URL
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multistoreSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | unselect store ||
+ ... || multistoreSKU${random} | AT ||
+ Repeat Keyword 3 Trigger multistore p&s
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Delete dynamic admin user from DB
+
+Multistore_CMS
+ [Documentation] Check CMS multistore functionality
+ Create dynamic admin user in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: Multistore Page${random} multistore-page${random} Multistore Page Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL on AT store if other store not specified: en/multistore-page${random}
+ Save current URL
+ Yves: page contains CMS element: CMS Page Title Multistore Page
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update cms page and publish it:
+ ... || cmsPage | unselect store ||
+ ... || Multistore Page${random} | AT ||
+ Trigger multistore p&s
+ Yves: navigate to specified AT store URL if no other store is specified and refresh until 404 occurs: ${url}
+ [Teardown] Run Keywords Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: Multistore Page${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_dms.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_dms.robot
new file mode 100644
index 0000000..c23f12a
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/multistore/multistore_dms.robot
@@ -0,0 +1,79 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_store_steps.robot
+Resource ../../../../resources/steps/products_steps.robot
+Resource ../../../../resources/steps/availability_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/zed_cms_page_steps.robot
+Resource ../../../../resources/steps/catalog_steps.robot
+Resource ../../../../resources/steps/zed_cms_block_steps.robot
+
+*** Test Cases ***
+Dynamic_multistore
+ [Documentation] This test should exclusively run for dynamic multi-store scenarios. The test verifies that the user can successfully create a new store, assign a product and CMS page, and register a customer within the new store.
+ [Tags] dms-on
+ Create dynamic admin user in DB
+ Create dynamic customer in DB
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create new Store:
+ ... || name | locale_iso_code | currency_iso_code | currency_code | currency_iso_code2 | currency_code2 | store_delivery_region | store_context_timezone ||
+ ... || ${random_str_store}_${random_str_store} | en_US | Euro | EUR | Swiss Franc | CHF | AT | Europe/Berlin ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: wait until store switcher contains: store=${random_str_store}_${random_str_store}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: update abstract product data:
+ ... || store | productAbstract ||
+ ... || ${random_str_store}_${random_str_store} | ${one_variant_product_abstract_sku} ||
+ Zed: update abstract product price on:
+ ... || productAbstract | store | mode | type | currency | amount | tax set ||
+ ... || ${one_variant_product_abstract_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 160.00 | Standard Taxes ||
+ Trigger multistore p&s
+ Zed: change concrete product data:
+ ... || productAbstract | productConcrete | active | searchable en | searchable de ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | true | true | true ||
+ Zed: change concrete product price on:
+ ... || productAbstract | productConcrete | store | mode | type | currency | amount ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | ${random_str_store}_${random_str_store} | gross | default | € | 15.00 ||
+ Zed: update warehouse:
+ ... || warehouse | store ||
+ ... || Warehouse1 | ${random_str_store}_${random_str_store} ||
+ Zed: change concrete product stock:
+ ... || productAbstract | productConcrete | warehouse n1 | warehouse n1 qty | warehouse n1 never out of stock ||
+ ... || ${one_variant_product_abstract_sku} | ${one_variant_product_concrete_sku} | Warehouse1 | 100 | true ||
+ Trigger multistore p&s
+ Zed: update abstract product data:
+ ... || productAbstract | name de ||
+ ... || ${one_variant_product_abstract_sku} | DEmanageProduct${random} force ||
+ Trigger multistore p&s
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: select currency Euro if other currency not specified
+ Yves: create new 'Shopping Cart' with name: storeCart+${random}
+ Yves: go to PDP of the product with sku: ${one_variant_product_concrete_sku}
+ Yves: product price on the PDP should be: €15.00
+ #### create new cms page and check it in new store on YVES
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: create a cms page and publish it: New Page Store${random} store-page${random} Page Title Page text
+ Trigger multistore p&s
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Title Page Title
+ Yves: page contains CMS element: CMS Page Content Page text
+ Yves: go to AT store 'Home' page if other store not specified: ${random_str_store}_${random_str_store}
+ Yves: go to newly created page by URL: en/store-page${random}
+ Yves: page contains CMS element: CMS Page Content Page text
+ ## assigned CMS BLocks to new store
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--html
+ Zed: assigned store to cms block: ${random_str_store}_${random_str_store} customer-registration_token--text
+ [Teardown] Run Keywords Should Test Run
+ ... AND Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ ... AND Zed: go to second navigation item level: Content Pages
+ ... AND Zed: click Action Button in a table for row that contains: New Page Store${random} Deactivate
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/manage_shipments.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/manage_shipments.robot
new file mode 100644
index 0000000..c0897be
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/manage_shipments.robot
@@ -0,0 +1,80 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Manage_Shipments
+ [Documentation] Checks create/edit shipment functions from backoffice
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Create dynamic customer in DB create_default_address=False
+ ... AND Deactivate all discounts in the database
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: 420575
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 420836
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: 420845
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select delivery to multiple addresses
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 420575 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 420836 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in new delivery address for a product:
+ ... || product | salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || 420845 | Dr. | First | Last | First Street | 1 | 10247 | Berlin | Germany | Spryker | 123456789 | Additional street ||
+ Yves: fill in the following new billing address:
+ ... || salutation | firstName | lastName | street | houseNumber | postCode | city | country | company | phone | additionalAddress ||
+ ... || Dr. | First | Last | Billing Street | 123 | 10247 | Berlin | Germany | Spryker | 987654321 | Additional street ||
+ Yves: click checkout button: Next
+ Yves: select the following shipping method for the shipment: 1 Hermes Next Day
+ Yves: submit form on the checkout
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_admin_user}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €86.99
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 1
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 1 | Hermes | Next Day | €15.00 | ASAP ||
+ Zed: create new shipment inside the order:
+ ... || delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | sku ||
+ ... || New address | Mr | Evil | Tester | ${dynamic_customer} | Austria | Hartmanngasse | 1 | Vienna | 1050 | DHL - Standard | 420845 ||
+ Zed: billing address for the order should be: First Last, Billing Street 123, 10247 Berlin, Germany
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 2
+ Zed: shipping address inside xxx shipment should be: 1 Dr First, Last, First Street, 1, Additional street, Spryker, 10247, Berlin, Germany
+ Zed: shipping address inside xxx shipment should be: 2 Mr Evil, Tester, Hartmanngasse, 1, 1050, Vienna, Austria
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: edit xxx shipment inside the order:
+ ... || shipmentN | delivery address | salutation | first name | last name | email | country | address 1 | address 2 | city | zip code | shipment method | requested delivery date | sku ||
+ ... || 2 | New address | Mr | Edit | Shipment | ${dynamic_customer} | Germany | Hartmanngasse | 9 | Vienna | 0987 | DHL - Express | 2025-01-25 | 420836 ||
+ Zed: order has the following number of shipments: ${lastPlacedOrder} 3
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 2 | DHL | Standard | €0.00 | ASAP ||
+ Zed: shipment data inside xxx shipment should be:
+ ... || shipment n | delivery method | shipping method | shipping costs | requested delivery date ||
+ ... || 3 | DHL | Express | €0.00 | 2025-01-25 ||
+ Zed: xxx shipment should/not contain the following products: 1 true 420575
+ Zed: xxx shipment should/not contain the following products: 1 false 420845
+ Zed: xxx shipment should/not contain the following products: 2 true 420845
+ Zed: xxx shipment should/not contain the following products: 3 true 420836
+ Zed: grand total for the order equals: ${lastPlacedOrder} €86.99
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/refunds.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/refunds.robot
new file mode 100644
index 0000000..75c135b
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/refunds.robot
@@ -0,0 +1,54 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+
+*** Test Cases ***
+Refunds
+ [Documentation] Checks that refund can be created for an item and the whole order of merchant
+ [Setup] Run keywords Create dynamic admin user in DB
+ ... AND Deactivate all discounts in the database
+ ... AND Create dynamic customer in DB
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: ${one_variant_product_of_main_merchant_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${multi_color_product_abstract_sku}
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: ${product_with_relations_related_products_sku}
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_merchant}
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,762.85
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state of xxx merchant's shipment: 1 send to distribution
+ Zed: trigger matching state of xxx merchant's shipment: 1 confirm at center
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Ship
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Deliver
+ Zed: trigger matching state of order item inside xxx shipment: 107254 Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €1,559.56
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state of xxx merchant's shipment: 1 Ship
+ Zed: trigger matching state of xxx merchant's shipment: 1 Deliver
+ Zed: trigger matching state of xxx merchant's shipment: 1 Refund
+ Zed: grand total for the order equals: ${lastPlacedOrder} €0.00
+ [Teardown] Delete dynamic admin user from DB
\ No newline at end of file
diff --git a/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/sales.robot b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/sales.robot
new file mode 100644
index 0000000..e54edc0
--- /dev/null
+++ b/atest/testdata/performance/tests/parallel_ui/mp_b2b/sales/sales.robot
@@ -0,0 +1,213 @@
+*** Settings ***
+Suite Setup UI_suite_setup
+Test Setup UI_test_setup
+Test Teardown UI_test_teardown
+Suite Teardown UI_suite_teardown
+Test Tags robot:recursive-stop-on-failure group_tree
+Resource ../../../../resources/common/common.robot
+Resource ../../../../resources/common/common_yves.robot
+Resource ../../../../resources/steps/zed_marketplace_steps.robot
+Resource ../../../../resources/steps/pdp_steps.robot
+Resource ../../../../resources/steps/orders_management_steps.robot
+Resource ../../../../resources/common/common_mp.robot
+Resource ../../../../resources/steps/mp_orders_steps.robot
+Resource ../../../../resources/steps/agent_assist_steps.robot
+Resource ../../../../resources/steps/order_comments_steps.robot
+
+*** Test Cases ***
+Return_Management
+ [Documentation] Checks OMS and that Yves user and in Zed main merchant can create/execute returns.
+ [Setup] Run Keywords Create dynamic customer in DB
+ ... AND Create dynamic admin user in DB
+ ... AND Zed: create dynamic merchant user: Spryker
+ ... AND Zed: create dynamic merchant user: merchant=Spryker merchant_user_group=Root group
+ Yves: login on Yves with provided credentials: ${dynamic_customer}
+ Yves: go to PDP of the product with sku: M90802
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M21711
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M90737
+ Yves: add product to the shopping cart
+ Yves: go to PDP of the product with sku: M72843
+ Yves: add product to the shopping cart
+ Yves: go to shopping cart page
+ Yves: click on the 'Checkout' button in the shopping cart
+ Yves: billing address same as shipping address: true
+ Yves: select the following existing address on the checkout as 'shipping' address and go next: ${default_address.full_address}
+ Yves: select the following shipping method on the checkout and go next: Express
+ Yves: select the following payment method on the checkout and go next: Marketplace Invoice
+ Yves: accept the terms and conditions: true
+ Yves: 'submit the order' on the summary page
+ Yves: 'Thank you' page is displayed
+ Yves: get the last placed order ID by current customer
+ Zed: login on Zed with provided credentials: ${dynamic_spryker_second_merchant}
+ Zed: go to order page: ${lastPlacedOrder}
+ Zed: trigger all matching states inside this order: skip grace period
+ Zed: trigger all matching states inside this order: Pay
+ Zed: go to my order page: ${lastPlacedOrder}
+ Zed: trigger matching state